10

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

我在很多地方都读过,因为 MD5 中的数字大于 php 可以处理的整数,所以这将是不准确的......因为无论如何我想要一个短 URL 并且不打算使用整个哈希,可能只有 8 个字符其中……

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

另外,只使用部分 MD5 哈希是不是一个坏主意?

4

9 回答 9

8

我将在这里提出不同的建议。由于您只对使用 md5 散列的十进制块感兴趣,为什么不使用任何其他短数字散列,例如CRC32Adler?这是一个例子:

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

这将生成您的字符串的 8 位哈希。

编辑:我想我误解了你,这里有一些函数提供到和从基数到 62 的转换

编辑(再次):要使用任意长度的数字,您必须使用 bc_math 或 GMP 扩展名,这是一个使用 bc_math 扩展名的函数,也可以从 base 2 转换为 base 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

希望能帮助到你。=)

于 2009-12-10T11:00:42.887 回答
4

如果可能的话,我建议不要为您的 URL 使用哈希。最终你会遇到冲突......特别是如果你截断哈希。如果您继续实施一个基于 id 的系统,其中每个项目都有一个唯一的 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 重新设置为 base-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));

希望这可以帮助!

如果您真的想要 base 62(不能用gmpor完成base_convert),请查看: http ://snipplr.com/view/22246/base62-encode--decode/

于 2009-12-10T11:19:30.573 回答
1

你可以这样做:(不是所有的步骤都在php中,我已经用了很长时间了。)

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

于 2009-12-10T11:05:45.493 回答
1

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

在此处查找 和 的toBase62()代码fromBase62()

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

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

于 2010-08-09T17:47:22.500 回答
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'])
于 2009-12-10T12:51:30.877 回答
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 。

于 2011-08-10T16:26:47.467 回答
0

这是一个将 MD5 字符串转换为 Base62 字符串的开源 Java 库 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

```

于 2018-04-05T11:48:58.833 回答
0

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

这是有关 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 
于 2016-02-24T02:32:10.870 回答
-1

您可以使用稍加修改的 Base 64 和-and_代替+and /

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);
于 2009-12-10T11:06:21.893 回答