我有一个将脚本转换为基数62(A-Za-z0-9)的脚本,但是如何从MD5中获取数字?
我已经在许多地方阅读到,因为MD5中的数字比PHP可以处理的整数要大,所以它会不准确...由于我需要一个短的URL,而且不打算使用整个哈希值,只使用其中的8个字符...
所以我的问题是如何获取MD5哈希的部分数字?
此外,仅使用MD5哈希的一部分是否是一个坏主意?
我有一个将脚本转换为基数62(A-Za-z0-9)的脚本,但是如何从MD5中获取数字?
我已经在许多地方阅读到,因为MD5中的数字比PHP可以处理的整数要大,所以它会不准确...由于我需要一个短的URL,而且不打算使用整个哈希值,只使用其中的8个字符...
所以我的问题是如何获取MD5哈希的部分数字?
此外,仅使用MD5哈希的一部分是否是一个坏主意?
我在这里提出了一个不同的建议。既然您只对使用md5哈希的十进制块感兴趣,为什么不使用其他短数字哈希,如CRC32或Adler?以下是一个示例:
$hash = sprintf('%u', crc32('your string here'));
echo bc_base_convert(md5('your url here'), 16, 62); // public base 62 hash
以及反向操作:
echo bc_base_convert('base 62 encoded value here', 62, 16); // private md5 hash
希望有所帮助。=)
1
,第二个将是2
等等——如果你正在使用MySQL,只需添加一个自增列即可。//the basic example
$sid = base_convert($id, 10, 36);
//if you're going to be needing 64 bit numbers converted
//on a 32 bit machine, use this instead
$sid = gmp_strval(gmp_init($id, 10), 36);
将短id转换为十进制id的方法:
//the basic example
$id = base_convert($id, 36, 10);
//if you're going to be needing 64 bit numbers
//on a 32 bit machine, use this instead
$id = gmp_strval(gmp_init($shortid, 36));
希望这可以帮到你!
如果你真的想要使用基数62(无法使用gmp
或base_convert
实现),请查看以下内容:http://snipplr.com/view/22246/base62-encode--decode/
你可以这样做:(并非所有步骤都是用php编写的,我已经很久没有使用它了。)
像这样创建脚本的md5哈希:
$hash = md5(script, raw_output=true);
将该数字转换为62进制。
请参阅有关在PHP中将任意大小的数字进行基础转换的问题。
将字符串截断到所需长度。
仅使用md5的几个位数没有风险。唯一改变的是碰撞的危险性。
实际上有一个Java实现,你可能可以提取它。这是一个名为Pulse的开源CMS解决方案。
在这里查看toBase62()
和fromBase62()
的代码。
http://pulse.torweg.org/javadoc/src-html/org/torweg/pulse/util/StringUtils.java.html
StringUtils
中唯一的依赖是 LifeCycle
类,它提供了一种获取字符串的盐哈希值的方法,你甚至可以完全省略它,或者将该方法复制到你自己的 StringUtils
中。就这样。
function base62hash($source, $chars = 22) {
return substr(gmp_strval(gmp_init(md5($source), 16), 62), 0, $chars);
}
将十六进制转换为六十二进制显然具有空间优势。一个普通的128位MD5哈希在十六进制中是32个字符,但在六十二进制中只有22个字符。如果您要将哈希存储在数据库中,可以将它们转换为原始二进制并节省更多的空间(对于MD5,仅需16字节)。
由于生成的哈希值只是一个字符串表示,因此如果您只想使用其中一部分(如函数所做的那样),则可以使用substr。
您可以尝试使用base62x来获得安全且兼容的编码表示。
这里提供有关base62x的更多信息, 或者在-NatureDNS
中简单地使用-base62x
。
shell> ./base62x -n 16 -enc 16AF
1Ql
shell> ./base62x -n 16 -dec 1Ql
16AF
shell> ./base62x
Usage: ./base62x [-v] [-n <2|8|10|16|32>] <-enc|dec> string
Version: 0.60
$hash = md5("The data to be hashed", true);
$ints = unpack("L*num", $hash);
$hash_str = base62($ints['num1']) . base62($ints['num2']) . base62($ints['num3']) . base62($ints['num4'])
这里有一个开源的Java库,可以将MD5字符串转换为Base62字符串 https://github.com/inder123/base62
Md5ToBase62.toBase62("9e107d9d372bb6826bd81d3542a419d6") ==> cbIKGiMVkLFTeenAa5kgO4
Md5ToBase62.fromBase62("4KfZYA1udiGCjCEFC0l") ==> 0000bdd3bb56865852a632deadbc62fc
这个转换是双向的,所以如果你将它转换回MD5,你将得到原始的MD5:
Md5ToBase62.fromBase62(Md5ToBase62.toBase62("9e107d9d372bb6826bd81d3542a419d6")) ==> 9e107d9d372bb6826bd81d3542a419d6
Md5ToBase62.toBase62(Md5ToBase62.fromBase62("cbIKGiMVkLFTeenAa5kgO4")) . ==> cbIKGiMVkLFTeenAa5kgO4
```
您可以使用稍微修改过的 Base 64,将+
和/
替换为-
和_
:
function base64_url_encode($str) {
return strtr(base64_encode($str), array('+'=>'-', '/'=>'_'));
}
function base64_url_decode($str) {
return base64_decode(strtr($str, array('-'=>'+', '_'=>'/')));
}
此外,您可以删除尾部填充的 =
字符。
要获取原始的 MD5 值(二进制字符串),请将第二个参数(在手册中命名为 $raw_output
)设置为 true:
$raw_md5 = md5($str, true);