首页 > 解决方案 > 用固定长度的字母编码数字?

问题描述

我有两个唯一的数字,100000 - 999999(固定 6 个字符长度[0-9]),第二个 1000000 - 9999999(固定 7 个字符长度[0-9])。我如何编码/解码这些数字(解码后它们需要保持分开),只使用大写字母[AZ][0-9]数字并且总共有 8 个字符的固定长度?

例子:

输入-> num_1:242404,num_2:1002000

编码 -> AX3B O3XZ

解码-> 2424041002000

有没有针对此类问题的算法?

标签: encryptionencoding

解决方案


这只是从一组值到另一组值的简单映射。程序始终相同:

  • 列出所有可能的输入和输出值。
  • 找到输入的索引。
  • 返回该索引处的输出列表的值。

请注意,通常不需要制作实际列表(即将所有值加载到某个数据结构中)。您通常可以按需计算任何索引的值。这个案子也不例外。

想象一下所有可能的输入对的列表:

0    100'000, 1'000'000
1    100'000, 1'000'001
2    100'000, 1'000'002
...
K    100'000, 9'999'999
K+1  100'001, 1'000'000
K+2  100'001, 1'000'001
...
N-1  999'999, 9'999'998
N    999'999, 9'999'999

对于任何给定的对 (a, b),您可以计算它在此列表中的索引 i,如下所示:

// Make a and b zero-based
a -= 100'000
b -= 1'000'000

i = a*1'000'000 + b

将 i 转换为基数 36(AZ 和 0-9 为您提供 36 个符号),根据需要在左侧填充零1,并在第四位数字后插入一个空格。

encoded = addSpace(zeroPad(base36(i)))

要返回输入对:

将 8 个字符的 base 36 字符串转换为 base 10(这是列表中的索引,记住),然后从索引中导出 a 和 b。

i = base10(removeSpace(encoded))

a = i/1'000'000 + 100'000    // integer divison (i.e. ignore remainder)
b = i%1'000'000 + 1'000'000

这是 Go 中的一个实现:https: //play.golang.org/p/KQu9Hcoz5UH


1如果您不喜欢零填充的想法,您也可以在此时偏移 i。目标值集足够大,您只需要大约 32% 的所有 base 36 数字,八位或更少。


推荐阅读