由于各种愚蠢的原因,我们发布到外部服务器的给定表单变量的最大长度为12个字符。
我想用md5模糊这个值,但很明显有12个字符不起作用。是否有一个已经制作的PHP函数的密码,这将导致12个字符或更少的字符?
密码的安全性和完整性在这里并不是非常重要。我的最后一招是编写一个函数,将每个字母向上或向下移动一个ascii值x。所以我们的目标不是让它从密码专家那里模糊不清,而只是不以纯文本形式发布它,这样看着它的非技术工作者就不会知道它是什么。
感谢您的任何建议。
答案 0 :(得分:16)
这是对this answer的补充。
答案建议从md5的32个字符表示中取出前12个字符。因此,将丢失20个字符的信息 - 这将导致方式更多可能的冲突。
您可以通过获取16个字符表示的前12个字符(原始表单)来减少信息丢失:
substr(md5($string, true), 0, 12);
这将保留75%的数据,而使用32个字符仅保留37.5%的数据。
答案 1 :(得分:16)
也许这会帮助你生成一个12字符串,你可以在URL中传递,而不会增加碰撞的风险
substr(base_convert(md5($string), 16,32), 0, 12);
答案 2 :(得分:9)
尝试使用crc32()?
答案 3 :(得分:8)
如果您只需要哈希,您仍然可以使用md5哈希中的前12个字符。
substr(md5($yourString), 0, 12);
答案 4 :(得分:4)
所有答案都建议丢失一些数据(更高的碰撞可能性),但看起来使用基本转换是一种更好的方法: 例如像这里描述的那样http://proger.i-forge.net/Short_MD5/OMF
您也可以生成任意随机字符串并将其插入数据库,在保存之前检查是否已存在。这将允许您使用短哈希,并确保没有冲突。
答案 5 :(得分:3)
我必须提出这个建议,因为我必须假设您已经控制了加密值发送到的脚本....
我还必须假设您可以创建多个表单字段,但它们的长度不能超过12个字符。
如果是这样的话,您是否可以简单地创建多个表单字段并将md5字符串分布在多个隐藏字段中?
您可以将md5字符串拆分为8个块,然后在隐藏的表单字段中提交每个块,然后在另一端将它们连接在一起。
只是一个想法...
答案 6 :(得分:0)
这可能不会对OP有用,因为他们正在寻找2向功能,但可能会帮助某些人寻找比md5短的哈希。这是我根据需要提出的(感谢https://rolandeckert.com/notes/md5突出显示base64_encode函数)。将md5哈希编码为base(64),并删除所有不需要的base(64)字符。我要删除元音+和/,因此将有效基数从64降低到52。
请注意,如果您在c个字符后截断了base(b)编码的哈希,它将允许b ^ c个唯一的哈希。这足够强大,可以避免碰撞吗?这取决于您要散列的项目数(k)。发生冲突的概率大约为(k * k)/(b ^ c)/ 2,因此,如果您使用下面的函数对k = 1百万个项目进行哈希处理,并且基础b = 52编码在c = 12个字符后被截断小于7.5亿分之一。与在c = 12个字符之后截断十六进制编码的(b = 16)哈希相比。发生碰撞的可能性约为500分之一!对截断十六进制编码的哈希值只说不。 :)
我会弯腰,说下面的功能(长度为12)对于1000万个物品(在750万碰撞的可能性中小于1)是相当安全的,但是如果您想更加安全地使用它, 64)编码(注释$ remove数组)和/或截断更少的字符。
// convert md5 to base64, remove undesirable characters and truncate to $length
function tinymd5($str, $length) { // $length 20-22 not advised unless $remove = '';
// remove vowels to prevent undesirable words and + / which may be problematic
$remove = array('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U', '+', '/');
$salt = $str;
do { // re-salt and loop if rebase removes too many characters
$salt = $base64 = base64_encode(md5($salt, TRUE));
$rebase = substr(str_replace($remove, '', $base64), 0, $length);
} while ($length < 20 && substr($rebase, -1) == '=');
return str_pad($rebase, min($length, 22), '='); // 22 is max possible length
}
$str = 'Lorem ipsum dolor sit amet 557726776';
echo '<br />' . md5($str); // 565a0bf7e0ba474fdaaec57b82e6504a
$x = md5($str, TRUE);
echo '<br />' . base64_encode($x); // VloL9+C6R0/arsV7guZQSg==
echo '<br />' . tinymd5($str, 12); // VlL9C6R0rsV7
echo '<br />' . tinymd5($str, 17); // VlL9C6R0rsV7gZQSg
$x = md5(base64_encode($x), TRUE); // re-salt triggered < 20
echo '<br />' . base64_encode($x); // fmkPW/OQLqp7PTex0nK3NQ==
echo '<br />' . tinymd5($str, 18); // fmkPWQLqp7PTx0nK3N
echo '<br />' . tinymd5($str, 19); // fmkPWQLqp7PTx0nK3NQ
echo '<br />' . tinymd5($str, 20); // fmkPWQLqp7PTx0nK3NQ=
echo '<br />' . tinymd5($str, 22); // fmkPWQLqp7PTx0nK3NQ===
答案 7 :(得分:0)
您可以使用较大的字母,并使哈希值更短,但仍可恢复为原始值。
我实现了here-例如,哈希ee45187ab28b4814cf03b2b4224eb974
变为7fBKxltZiQd7TFsUkOp26w
-它从32个字符变为22个字符。如果您使用较大的alpahabet,它的数量甚至会更少。如果您使用unicode,甚至可以使用表情符号对哈希进行编码...
答案 8 :(得分:0)
$ hashlen = 4;
$ cxtrong = TRUE;
$ sslk = openssl_random_pseudo_bytes($ hashlen,$ cxtrong);
$ rand = bin2hex($ sslk);
echo $ rand;
您可以通过更改变量$ hashlen的值来更改哈希长度(以2的倍数)