Dalam proses pembangunan merentas bahasa, kita sering menghadapi situasi di mana kita perlu menterjemah algoritma atau fungsi daripada satu bahasa ke bahasa lain. Dalam proses ini, terjemahan blok CRC32 adalah keperluan biasa. Walau bagaimanapun, menterjemah blok CRC32 ini daripada Pergi ke JavaScript bukanlah tugas yang mudah. Dalam artikel ini, editor PHP Xigua akan memperkenalkan cara menterjemah blok CRC32 ini dengan betul daripada Pergi ke JavaScript untuk membantu pembangun menyelesaikan masalah ini.
Saya mempunyai fungsi ini:
package main import ( "fmt" "github.com/snksoft/crc" ) var crctable *crc.table func init() { params := crc.crc32 params.finalxor = 0 params.reflectout = false crctable = crc.newtable(params) } func crccalculateblock(data []byte) uint32 { if len(data)%4 > 0 { panic("block size needs to be a multiple of 4") } h := crc.newhashwithtable(crctable) var buf [4]byte for i := 0; i < len(data); i += 4 { buf[0] = data[i+3] buf[1] = data[i+2] buf[2] = data[i+1] buf[3] = data[i+0] h.update(buf[:]) } return h.crc32() } func main() { data := []byte{1, 2, 3, 4, 5, 6, 7, 8} crc := crccalculateblock([]byte(data)) fmt.printf("crc is 0x%04x\n", crc) }
Hasilnya ialah: 0x948b389d
Saya cuba menterjemah ini kepada javascript tetapi saya kehilangan sesuatu:
var makeCRCTable = function(){ var c; var crcTable = []; for(var n =0; n < 256; n++){ c = n; for(var k =0; k < 8; k++){ c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); } crcTable[n] = c; } return crcTable; } var crc32 = function(u8array) { var crcTable = window.crcTable || (window.crcTable = makeCRCTable()); var crc = 0 ^ (-1); for (var i = 0; i < u8array.length; i+=4 ) { crc = (crc >>> 8) ^ crcTable[(crc ^ u8array[i+3]) & 0xFF]; crc = (crc >>> 8) ^ crcTable[(crc ^ u8array[i+2]) & 0xFF]; crc = (crc >>> 8) ^ crcTable[(crc ^ u8array[i+1]) & 0xFF]; crc = (crc >>> 8) ^ crcTable[(crc ^ u8array[i]) & 0xFF]; } return (crc ^ (-1)) >>> 0; }; console.log(crc32(Uint8Array.from([1,2,3,4,5,6,7,8])).toString(16))
Tetapi hasilnya berbeza. (46e32ed6)
Walaupun tanpa XOR akhir saya mendapat b91cd129
Bolehkah sesiapa menerangkan kepada saya bagaimana untuk membetulkan ini dan mengapa ini salah?
Terdapat dua perbezaan:
perlaksanaan go telah dipanggil reflect
(lihat https://www.php.cn/link/f23775b54b9e62e2d15498c3b9418630):
if t.crcparams.reflectout != t.crcparams.reflectin { ret = reflect(ret, t.crcparams.width) }
go (finalxor
是 0
(params.finalxor = 0
) 而在 js 中是 -1
kembali (crc ^ (-1)) phpcngt phpcn>> 0;phpcnendc phpcn)
var makeCRCTable = function () { var c; var crcTable = []; for (var n = 0; n < 256; n++) { c = n; for (var k = 0; k < 8; k++) { c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; } crcTable[n] = c; } return crcTable; }; var crc32 = function (u8array) { var crcTable = window.crcTable || (window.crcTable = makeCRCTable()); var crc = 0 ^ -1; for (var i = 0; i < u8array.length; i += 4) { crc = (crc >>> 8) ^ crcTable[(crc ^ u8array[i + 3]) & 0xff]; crc = (crc >>> 8) ^ crcTable[(crc ^ u8array[i + 2]) & 0xff]; crc = (crc >>> 8) ^ crcTable[(crc ^ u8array[i + 1]) & 0xff]; crc = (crc >>> 8) ^ crcTable[(crc ^ u8array[i]) & 0xff]; } crc = reverseBits(crc, 32); return (crc ^ 0) >>> 0; }; function reverseBits(integer, bitLength) { if (bitLength > 32) { throw Error( 'Bit manipulation is limited to <= 32 bit numbers in JavaScript.' ); } let result = 0; for (let i = 0; i < bitLength; i++) { result |= ((integer >> i) & 1) << (bitLength - 1 - i); } return result >>> 0; // >>> 0 makes it unsigned even if bit 32 (the sign bit) was set } console.log(crc32(Uint8Array.from([1, 2, 3, 4, 5, 6, 7, 8])).toString(16));
Atas ialah kandungan terperinci Bagaimana untuk menterjemah blok CRC32 ini dengan betul daripada Pergi ke JavaScript?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!