簡體   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