将MD5转换为base62以获取URL

时间:2009-12-10 10:49:36

标签: php md5 base62

我有一个脚本要转换为base 62(A-Za-z0-9),但如何从MD5中获取数字?

我在很多地方都读到,因为MD5中的数字大于php可以处理的整数,所以它将是不准确的...因为我想要一个简短的URL而不是计划使用整个哈希,也许只有8个字符......

所以我的问题是如何获得MD5哈希值的一部分?

仅使用部分MD5哈希是一个坏主意吗?

9 个答案:

答案 0 :(得分:6)

我将在这里建议一个不同的东西..因为你只对使用md5哈希的十进制块感兴趣,为什么不使用任何其他短数字哈希,如CRC32或{{3 }}?这是一个例子:

$hash = sprintf('%u', crc32('your string here'));

这将产生字符串的8位哈希值。

编辑:我想我误解了你,Adler

编辑(再次):要使用任意长度的数字,您必须使用bc_math或GMP扩展名here are some functions that provide conversions to and from bases up to 62。你应该像这样使用它:

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 :(得分:3)

如果可能的话,我建议不要为您的网址使用哈希值。最终你会遇到冲突......特别是如果你正在截断哈希。如果你继续实施一个基于身份的系统,其中每个项目都有一个唯一的ID,那么就会有更少的麻烦。第一项是1,第二项是2等等 - 如果你使用MySQL,只需输入一个自动增量列。

制作一个简短的ID:

//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重新设置为基数为10的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(无法使用gmpbase_convert完成),请查看以下内容: http://snipplr.com/view/22246/base62-encode--decode/

答案 2 :(得分:1)

你可以这样做:(并非所有步骤都在php中,我用了很长时间了。)

仅使用md5的几个位没有风险。所有这些变化都是碰撞的危险。

答案 3 :(得分:1)

实际上有一个Java实现可以提取。它是一个名为Pulse的开源CMS解决方案。

点击此处查看toBase62()fromBase62()的代码。

http://pulse.torweg.org/javadoc/src-html/org/torweg/pulse/util/StringUtils.java.html

StringUtils中唯一的依赖项是LifeCycle类,它提供了一种获取字符串的盐渍哈希的方法,您甚至可以将其全部省略,或者只是将方法复制到您的副本StringUtils 。瞧。

答案 4 :(得分:0)

您可以使用略有修改的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);

答案 5 :(得分:0)

你可以这样做,

$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'])

答案 6 :(得分:0)

从PHP 5.3.2开始,GMP支持最多62个基础(之前只有36个),因此brianreavis的建议非常接近。我认为对你的问题最简单的答案是:

function base62hash($source, $chars = 22) {
  return substr(gmp_strval(gmp_init(md5($source), 16), 62), 0, $chars);
}

从base-16转换为base-62显然具有空间优势。普通的128位MD5哈希是十六进制的32个字符,但在base-62中它只有22.如果你将哈希值存储在数据库中,你可以将它们转换为原始二进制文件并节省更多空间(16个字节用于MD5)。

由于生成的哈希只是一个字符串表示,如果你只需要一点它就可以使用substr(就像函数一样)。

答案 7 :(得分:0)

您可以尝试使用base62x来获得安全且兼容的编码表示。

Here is for more information about base62x,或-base62x中的-NatureDNS

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 

答案 8 :(得分:0)

这是一个开源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

```