将长整数ID散列为较小的字符串

时间:2016-06-06 11:04:13

标签: algorithm hash

这是问题所在,我需要将ID(定义为长整数)转换为较小的alfanumeric标识符。详情如下:

  • 每个人都将问题作为一个唯一的ID,一个13的长整数(类似于123123412341234)。
  • 我需要生成一个这个唯一ID的小型表示,一个alfanumeric字符串,类似于A1CB3X。问题是5或6个字符的长度不足以代表这么大的整数。
  • 新ID(例如A1CB3X)应该在我们知道只存在少量个体(少于500个)的环境中有效。新ID在这一小部分人中应该是独一无二的。
  • 新ID(例如A1CB3X)应该是对原始ID进行计算的结果。这意味着在其他地方获取原始ID并应用相同的计算,我们应该获得相同的新ID(例如A1CB3X)。
  • 当个人被添加到集合中时,应该进行此计算,这意味着当时不会知道属于该集合的所有个人。

关于如何解决这个问题的任何指示?

4 个答案:

答案 0 :(得分:1)

假设您不需要两个方向的公式(如果您将13位数字减少为5或6个字符的字母数字字符串则不可能):

如果您最多可以有6个字母数字字符,那么就可以使用36 6 = 2,176,782,336种可能性,假设只有数字和大写字母。

要将较大的13位数字映射到此空间,您可以采用略小于该值的某个素数的模数,例如2,176,782,317,使用base-36编码对其进行编码。

alphanum_id = base36encode(longnumber_id % 2176782317)

对于一组500,这会给你一个

2176782317 P 500 / 2176782317 500 发生碰撞的机会

(P是排列)

答案 1 :(得分:1)

最佳选择是使用区分大小写的字符将基数更改为62

如果希望缩短,可以添加unicode字符。见下文。

以下是您的javascript代码:https://jsfiddle.net/vewmdt85/1/

function compress(n) {
    var symbols = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïð'.split('');
    var d = n;
    var compressed = '';

    while (d >= 1) {
        compressed = symbols[(d - (symbols.length * Math.floor(d / symbols.length)))] + compressed;
        d = Math.floor(d / symbols.length);
    }

    return compressed;
}

$('input').keyup(function() {
        $('span').html(compress($(this).val()))
})

$('span').html(compress($('input').val()))

答案 2 :(得分:0)

如何使用某些base-X转换,例如123123412341234 17N644R7CI变为99999999999993JLXPT2PR变为System.setProperty

答案 3 :(得分:0)

如果你需要一个既可以使用两个方向的映射,也可以选择更大的基础

含义:使用base 16,您可以将1到16减少为单个字符。 因此,base36是允许更短字符串的“最大值”(当需要1-1映射时)!