php 将 MD5 哈希表示为整数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1422725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Represent MD5 hash as an integer
提问by caw
In my user database table, I take the MD5 hash of the email address of a user as the id.
在我的用户数据库表中,我将用户电子邮件地址的 MD5 哈希值作为 id。
Example: email([email protected]) = id(d41d8cd98f00b204e9800998ecf8427e)
例子: email([email protected]) = id(d41d8cd98f00b204e9800998ecf8427e)
Unfortunately, I have to represent the ids as integer values now - in order to be able to use an API where the id can only be an integer.
不幸的是,我现在必须将 id 表示为整数值 - 为了能够使用 id 只能是整数的 API。
Now I'm looking for a way to encode the id into an integer for sending an decode it again when receiving. How could I do this?
现在我正在寻找一种将 id 编码为整数的方法,以便在接收时再次发送解码。我怎么能这样做?
My ideas so far:
到目前为止我的想法:
convert_uuencode()andconvert_uudecode()for the MD5 hash- replace every character of the MD5 hash by its
ord()value
convert_uuencode()和convert_uudecode()MD5 哈希- 用其
ord()值替换 MD5 散列的每个字符
Which approach is better? Do you know even better ways to do this?
哪种方法更好?你知道更好的方法吗?
I hope you can help me. Thank you very much in advance!
我希望你能帮助我。非常感谢您提前!
采纳答案by bdonlan
Be careful. Converting the MD5s to an integer will require support for big (128-bit) integers. Chances are the API you're using will only support 32-bit integers - or worse, might be dealing with the number in floating-point. Either way, your ID will get munged. If this is the case, just assigning a second ID arbitrarily is a much better way to deal with things than trying to convert the MD5 into an integer.
当心。将 MD5 转换为整数将需要支持大(128 位)整数。您使用的 API 可能只支持 32 位整数 - 或者更糟的是,可能正在处理浮点数。无论哪种方式,您的 ID 都会被篡改。如果是这种情况,与尝试将 MD5 转换为整数相比,仅任意分配第二个 ID 是一种更好的处理方式。
However, if you are surethat the API can deal with arbitrarily large integers without trouble, you can just convert the MD5 from hexadecimal to an integer. PHP most likely does not support this built-in however, as it will try to represent it as either a 32-bit integer or a floating point; you'll probably need to use the PHP GMP libraryfor it.
但是,如果您确定API 可以毫无困难地处理任意大的整数,则只需将 MD5 从十六进制转换为整数即可。然而,PHP 很可能不支持这个内置函数,因为它会尝试将其表示为 32 位整数或浮点数;您可能需要为此使用PHP GMP 库。
回答by GZipp
There are good reasons, stated by others, for doing it a different way.
其他人说,有很好的理由以不同的方式来做。
But if what you want to do is convert an md5 hash into a string of decimal digits(which is what I think you really mean by "represent by an integer", since an md5 is already an integer in string form), and transform it back into the same md5 string:
但是,如果您想要做的是将 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);
}
Demo:
演示:
$md5 = md5('[email protected]');
echo $md5 . '<br />'; // 23463b99b62a72f26ed677cc556c44e8
$dec = md5_hex_to_dec($md5);
echo $dec . '<br />'; // 0903015257466342942628374306682186817640
$hex = md5_dec_to_hex($dec);
echo $hex; // 23463b99b62a72f26ed677cc556c44e8
Of course, you'd have to be careful using either string, like making sure to use them only as string type to avoid losing leading zeros, ensuring the strings are the correct lengths, etc.
当然,您必须小心使用任一字符串,例如确保仅将它们用作字符串类型以避免丢失前导零,确保字符串长度正确等。
回答by codebard
For a 32-bit condensation, a simple solution could be made by selecting 4 hex pairs (8 characters) of the MD5 hash, where each pair represents one byte, and then converting that with intval().
对于 32 位压缩,可以通过选择 MD5 散列的 4 个十六进制对(8 个字符)来制作一个简单的解决方案,其中每一对代表一个字节,然后将其转换为intval().
For an unsigned 32-bit Int:
对于无符号 32 位 Int:
$inthash = intval(substr(md5($str), 0, 8), 16);
For the positive value only of a signed 32-bit Int:
仅对于有符号 32 位 Int 的正值:
$inthash = intval(substr(md5($str), 0, 8), 16) >> 1;
This will likely only work for values up to 64-bit (8 bytes or 16 characters) for most modern systems as noted in the docs.
如文档中所述,对于大多数现代系统,这可能仅适用于高达 64 位(8 个字节或 16 个字符)的值。
On a system that can accommodate 64-bit Ints, a splitting strategy that consumes the entire 128-bit MD5 hash as 2 Ints might look like:
在可以容纳 64 位整数的系统上,将整个 128 位 MD5 哈希消耗为 2 个整数的拆分策略可能如下所示:
$hash = md5($str);
$inthash1 = intval(substr($hash, 0, 16), 16);
$inthash2 = intval(substr($hash, 16, 16), 16);
回答by Alexey Sviridov
Why ord()? md5 produce normal 16-byte value, presented to you in hex for better readability. So you can't convert 16-byte value to 4 or 8 byte integer without loss. You must change some part of your algoritms to use this as id.
为什么是 ord()?md5 产生正常的 16 字节值,以十六进制呈现给您以提高可读性。因此,您无法将 16 字节值转换为 4 或 8 字节整数而不会丢失。您必须更改算法的某些部分才能将其用作 ID。
回答by Marcin
what about:
关于什么:
$float = hexdec(md5('string'));
$float = hexdec(md5('string'));
or
或者
$int = (integer) (substr(hexdec(md5('string')),0,9)*100000000);
$int = (integer) (substr(hexdec(md5('string')),0,9)*100000000);
Definietly bigger chances for collision but still good enaugh to use instead of hash in DB though?
绝对有更大的碰撞机会,但仍然可以在数据库中使用而不是散列?
cheers,
干杯,
/Marcin
/马尔钦
回答by SeanJA
Couldn't you just add another field that was an auto-increment int field?
难道您不能添加另一个作为自增 int 字段的字段吗?
回答by Malax
回答by humbads
Use the email address as the file name of a blank, temporary file in a shared folder, like /var/myprocess/[email protected]
使用电子邮件地址作为共享文件夹中空白临时文件的文件名,例如 /var/myprocess/[email protected]
Then, call ftok on the file name. ftok will return a unique, integer ID.
然后,对文件名调用 ftok。ftok 将返回一个唯一的整数 ID。
It won't be guaranteed to be unique though, but it will probably suffice for your API.
虽然不能保证它是唯一的,但它可能足以满足您的 API。

