我试图使用Crockford Base32 Algorithm编码一个字符串。在PHP中实现Crockford Base32编码
不幸的是,my current code只接受数值作为输入。我想将ASCII字符转换为十进制或八进制,但是010
和100
的连接结果为10100
,这使得无法对此进行解码。有没有办法做到这一点我不知道?
我试图使用Crockford Base32 Algorithm编码一个字符串。在PHP中实现Crockford Base32编码
不幸的是,my current code只接受数值作为输入。我想将ASCII字符转换为十进制或八进制,但是010
和100
的连接结果为10100
,这使得无法对此进行解码。有没有办法做到这一点我不知道?
我相信这应该是一个更有效的实现的Crockford Base32 encoding:
function crockford_encode($base10) {
return strtr(base_convert($base10, 10, 32),
"abcdefghijklmnopqrstuv",
"ABCDEFGHJKMNPQRSTVWXYZ");
}
function crockford_decode($base32) {
$base32 = strtr(strtoupper($base32),
"ABCDEFGHJKMNPQRSTVWXYZILO",
"abcdefghijklmnopqrstuv110");
return base_convert($base32, 32, 10);
}
需要注意的是,由于PHP的base_convert()
功能已知的限制(或者,可以说,漏洞),这些函数只会返回正确的结果,以便可以用PHP的内部数值类型(可能是双精度值)准确表示值。我们希望这将在未来的某个PHP版本中得到解决,但同时,您可以始终使用this drop-in replacement for base_convert()
。
编辑:计算可选校验数位最简单的方法可能是只是这样的:
function crockford_check($base10) {
return substr("ABCDEFGHJKMNPQRSTVWXYZ*~$=U", $base10 % 37, 1);
}
,或者对于大量:
function crockford_check($base10) {
return substr("ABCDEFGHJKMNPQRSTVWXYZ*~$=U", bcmod($base10, 37), 1);
}
我们就可以使用它是这样的:
function crockford_encode_check($base10) {
return crockford_encode($base10) . crockford_check($base10);
}
function crockford_decode_check($base32) {
$base10 = crockford_decode(substr($base32, 0, -1));
if (strtoupper(substr($base32, -1)) != crockford_check($base10)) {
return null; // wrong checksum
}
return $base10;
}
注:(2014年7月18日)代码的最初版本以上曾在克罗克福德字母串的错误,这样他们阅读...WZYZ
代替...WXYZ
,导致一些号码是编码和解码不正确。这个bug现在已经被修复了,codepad.org版本现在包含一个基本的自测例程来验证这个。感谢James Firth发现错误并修复它。
文档正在向函数传递一个字符串? 'Crockford :: encode('519571');' – BenM
如果你看看源代码,这些将被转换为整数 – Stefan
我做了一个(非常糟糕的)Base32库,你可以试试:https://github.com/NTICompass/PHP -Base32 –