繁体   English   中英

在PHP中实现Crockford Base32编码

[英]Implementing the Crockford Base32 encoding in PHP

我正在尝试使用Crockford Base32算法对字符串进行编码。

不幸的是, 我当前的代码只接受数值作为输入。 我想到将ASCII字符转换为十进制或八进制,但是然后010100的串联导致10100 ,这使得无法对此进行解码。 有没有办法做到这一点,我不知道?

我相信这应该是一个更有效的Crockford Base32编码实现

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 );
}

在codepad.org上演示

请注意,由于PHP的base_convert()函数中的已知限制(或者,可以说是错误),这些函数只会返回正确的结果,这些值可以由PHP的内部数字类型(可能是double)准确表示。 我们希望这将在未来的PHP版本中得到修复,但与此同时,您可以随时使用base_convert() - base_convert()替代品


编辑:计算可选校验位的最简单方法可能就是这样:

function crockford_check( $base10 ) {
    return substr( "0123456789ABCDEFGHJKMNPQRSTVWXYZ*~$=U", $base10 % 37, 1 );
}

或者,对于大数字:

function crockford_check( $base10 ) {
    return substr( "0123456789ABCDEFGHJKMNPQRSTVWXYZ*~$=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;
}

在codepad.org上演示

注意: (2014年7月18日)上面代码的原始版本在Crockford字母表字符串中有一个错误,因此它们读取...WZYZ而不是...WXYZ ,导致某些数字被编码和解码不正确。 这个bug现在已得到修复,而codepad.org版本现在包含一个基本的自测例程来验证这一点。 感谢James Firth发现了这个漏洞并修复它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM