创建哈希函数以将6个数字映射到短字符串

时间:2018-01-10 04:20:30

标签: algorithm hash mapping

我有6个变量0 ≤ n₁,...,n₆ ≤ 12,我想构建一个哈希函数来进行直接映射D(n₁,n₂,n₃,n₄,n₅,n₆) = S,另一个函数来做逆映射I(S) = (n₁,n₂,n₃,n₄,n₅,n₆),其中S是一个字符串(az,AZ,0-9)。

我的目标是将S的长度减至3或更短。

我认为变量有13个可能的值,单个字母(az)应该能够代表其中的两个,但我意识到1 + 12 = m2 + 11 = m,所以我仍然没有&#39 ; t知道如何编写函数。

是否有任何方法可以构建一个执行此映射的函数并返回一个小字符串?

如果需要,可以使用整个ASCII来表示S。

2 个答案:

答案 0 :(得分:1)

  

我认为变量有13个可能的值,一个字母   (a-z)应该能够代表其中的两个

这种推理是错误的。实际上,要表示两个变量(=这些变量可能采用的任何组合),您将需要13x13 = 169个符号。

对于您的示例,6个变量可以采用13 ^ 6(= 4826809)个不同的组合。为了表示所有可能的组合,您将需要5个字母(a-z),因为26 ^ 5(= 11881376)是产生超过13 ^ 6个组合的最小量。

对于ASCII字符,3个符号应该足够,因为256 ^ 3> 13 ^ 6。

如果您仍然对进行转换的代码感兴趣,我将很乐意为您提供帮助。

答案 1 :(得分:1)

您可以使用基本转化将任意给定范围内的一组数字转换为任何其他范围内的数字。

二进制是基数2(0-1),十进制是基数10(0-9)。你的6个号码是13号(0-12)。

检查是否可以进行转换涉及计算每组的可能值组合的数量。每个数字在[0,n]范围内(因此基数为n + 1),我们可以从全0到全部为n,因此每个数字可以取n + 1个值,可能性总数为(n + 1) ) numberCount 。例如,对于6个十进制数字,它将是10 6 = 1000000,其检出,因为存在1000000个可能的数字(最多)6个数字,即数字<1。百万。

大写字母和数字(26 + 26 + 10)将是62(0-61),但是,从上面开始,3个这样的值不足以代表你的6个数字(13 6 &gt; 62 3 )。要从/向这些转换,您可以转换为一组基数为62的数字,然后使用适当的if语句转换为0-9&lt; =&gt; 0-9,a-z&lt; =&gt; 10-35,A-Z = 36-61。

您可以用3个字节表示您的数据(因为256 3 &gt; = 13 6 ),尽管这不一定是可打印的字符 - 32-126是考虑到标准可打印范围(范围仍然太小),128-255是扩展范围,可能无法在任何给定环境中正确显示(为了最好地正确显示它,你应该至少避免0 -31和127,它们是控制字符 - 您可以通过添加32将0 -...转换为上述范围,然后在值>> 127时添加另一个1。

许多/大多数语言应该允许您给出一个数值来表示一个字符,所以在进行基本转换后输出它应该相当简单。虽然有些人可能会使用Unicode来表示字符,但这可能会使用ASCII工作变得不那么简单。

如果数字具有特定约束,则会减少可能的组合数量,从而可能使其适合较小的数字集或范围。

要进行实际的基本转换:

首先将它转换为常规整数类型(通常是二进制或十进制)可能是最简单的,我们不必担心基数,然后将其转换为目标基数(尽管首先确保您的值将适合您正在使用的任何数据类型。

考虑二进制如何工作:

1101 is 13 = 23 + 22 + 20

13 % 2 = 1   13 / 2 = 6
6  % 2 = 0    6 / 2 = 3
3  % 2 = 1    3 / 2 = 1
1  % 2 = 1
The above, from top to bottom: 1101 = our number

使用相同的想法,我们可以按如下方式转换为/来自任何基数:(伪代码)

int convertFromBase(array, base):
   output = 0
   for each i in array
      output = base*output + i
   return output

int[] convertToBase(num, base):
   output = []
   while num > 0
      output.append(num % base)
      num /= base
   output.reverse()
   return output

您还可以将此逻辑扩展到每个数字在不同范围内的情况,方法是在每个步骤中更改您的除数或倍数(详细解释可能有点超出问题的范围)。