[英]Implementing the Crockford Base32 encoding in PHP
我正在嘗試使用Crockford Base32算法對字符串進行編碼。
不幸的是, 我當前的代碼只接受數值作為輸入。 我想到將ASCII字符轉換為十進制或八進制,但是然后010
和100
的串聯導致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.