diff --git a/GameFrameX.Foundation.Hash/CrcHelper.cs b/GameFrameX.Foundation.Hash/CrcHelper.cs index 8e3e673..f00824b 100644 --- a/GameFrameX.Foundation.Hash/CrcHelper.cs +++ b/GameFrameX.Foundation.Hash/CrcHelper.cs @@ -295,30 +295,37 @@ internal static int GetCrc32(Stream stream, byte[] code, int length) var cachedBytes = new byte[CachedBytesLength]; var algorithm = new Crc32(); var codeIndex = 0; - while (true) + int bytesRead; + while ((bytesRead = stream.Read(cachedBytes, 0, CachedBytesLength)) > 0) { - var bytesRead = stream.Read(cachedBytes, 0, CachedBytesLength); - if (bytesRead > 0) - { - if (length > 0) - { - for (var i = 0; i < bytesRead && i < length; i++) - { - cachedBytes[i] ^= code[codeIndex++]; - codeIndex %= codeLength; - } - - length -= bytesRead; - } - - algorithm.HashCore(cachedBytes, 0, bytesRead); - } - else + if (length > 0) { - break; + XorWithCode(cachedBytes, bytesRead, length, code, codeLength, ref codeIndex); + length -= bytesRead; } + + algorithm.HashCore(cachedBytes, 0, bytesRead); } return (int)algorithm.HashFinal(); } + + /// + /// 将 循环异或到 的前 min(bytesRead, length) 个字节,并通过 维护回绕位置。 + /// + /// 目标缓冲区 / The target buffer to XOR into + /// 本次从流读到的字节数 / Bytes read from the stream in this iteration + /// 剩余可异或字节数(<= 0 时调用方应跳过) / Remaining bytes available to XOR + /// 用于异或的字节码 / The code byte array to XOR with + /// 的长度 / Length of the code + /// 循环异或的当前游标(按引用传递,调用方负责初始化为 0) / Current rotation index, passed by ref + private static void XorWithCode(byte[] buffer, int bytesRead, int length, byte[] code, int codeLength, ref int codeIndex) + { + var count = Math.Min(bytesRead, length); + for (var i = 0; i < count; i++) + { + buffer[i] ^= code[codeIndex]; + codeIndex = (codeIndex + 1) % codeLength; + } + } }