在我的用户数据库表中,我将用户电子邮件地址的MD5哈希值作为id。

示例: email(example@example.org)= id(d41d8cd98f00b204e9800998ecf8427e)

不幸的是,我现在必须将id表示为整数值 - 以便能够使用其中id只能是整数的API。

现在我正在寻找一种方法将id编码为一个整数,以便在接收时再次发送解码。我怎么能这样做?

到目前为止我的想法:

    MDL哈希的
  1. convert_uuencode() convert_uudecode()
  2. 用其 ord()
  3. 替换MD5哈希的每个字符

    哪种方法更好?你知道更好的方法吗?

    我希望你能帮助我。非常感谢你提前!

有帮助吗?

解决方案

小心点。将MD5转换为整数将需要支持大(128位)整数。有可能你正在使用的API只支持32位整数 - 或者更糟糕的是,可能正在处理浮点数。无论哪种方式,你的身份证都会受到影响。如果是这种情况,只需任意分配第二个ID就可以比处理将MD5转换为整数更好的处理方式。

但是,如果您确定 API可以毫无问题地处理任意大整数,则可以将MD5从十六进制转换为整数。 PHP很可能不支持这种内置,因为它会尝试将其表示为32位整数或浮点数;您可能需要使用 PHP GMP库

其他提示

其他人说,有充分的理由以不同的方式做到这一点。

但是如果你想要做的是将md5哈希转换为字符串 十进制数字(这是我认为你真正的意思 “由整数表示”,因为md5已经是字符串形式的整数), 并将其转换回相同的md5字符串:

function md5_hex_to_dec($hex_str)
{
    $arr = str_split($hex_str, 4);
    foreach ($arr as $grp) {
        $dec[] = str_pad(hexdec($grp), 5, '0', STR_PAD_LEFT);
    }
    return implode('', $dec);
}

function md5_dec_to_hex($dec_str)
{
    $arr = str_split($dec_str, 5);
    foreach ($arr as $grp) {
        $hex[] = str_pad(dechex($grp), 4, '0', STR_PAD_LEFT);
    }
    return implode('', $hex);
}

演示:

$md5 = md5('example@example.com');
echo $md5 . '<br />';  // 23463b99b62a72f26ed677cc556c44e8
$dec = md5_hex_to_dec($md5);
echo $dec . '<br />';  // 0903015257466342942628374306682186817640
$hex = md5_dec_to_hex($dec);
echo $hex;             // 23463b99b62a72f26ed677cc556c44e8

当然,您必须小心使用任一字符串,例如确保仅将它们用作字符串类型以避免丢失前导零,确保字符串是正确的长度等。

对于32位压缩,可以通过选择MD5哈希的4个十六进制对(8个字符)来做出简单的解决方案,其中每对代表一个字节,然后用 intval()

对于无符号的32位Int:

$inthash = intval(substr(md5($str), 0, 8), 16);

仅对有符号的32位Int:

的正值
$inthash = intval(substr(md5($str), 0, 8), 16) >> 1;

对于大多数现代系统,这可能仅适用于最多64位(8字节或16个字符)的值,如文档中所述。

在一个可以容纳64位Ints的系统上,一个将整个128位MD5哈希消耗为2 Ints的分裂策略可能如下所示:

$hash = md5($str);
$inthash1 = intval(substr($hash, 0, 16), 16);
$inthash2 = intval(substr($hash, 16, 16), 16);

您可以使用 hexdec 来解析十六进制字符串和存储数据库中的数字。

难道你不能只添加另一个自动增量int字段吗?

为什么选择ord()? md5产生正常的16字节值,以十六进制显示,以提高可读性。因此,您无法将16字节值转换为4或8字节整数而不会丢失。您必须更改算法的某些部分才能将其用作id。

怎么样:

$ float = hexdec(md5('string'));

$ int =(整数)(substr(hexdec(md5('string')),0,9)* 100000000);

肯定会有更大的碰撞机会但是仍然可以在DB中使用而不是哈希?

欢呼声,

/马尔钦

使用电子邮件地址作为共享文件夹中空白临时文件的文件名,例如/var/myprocess/example@example.org

然后,在文件名上调用ftok。 ftok将返回唯一的整数ID。

虽然不能保证它是唯一的,但它可能足以满足您的API。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top