From a4455cf9a621a62ea5e284ffd428ff7ca8765fec Mon Sep 17 00:00:00 2001 From: Blank Date: Thu, 30 Jul 2026 02:30:30 +0800 Subject: [PATCH] =?UTF-8?q?refactor(hash):=20=E9=99=8D=E4=BD=8E=20CrcHelpe?= =?UTF-8?q?r.GetCrc32(Stream,=20byte[],=20int)=20=E8=AE=A4=E7=9F=A5?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Linear: GFX-206 --- GameFrameX.Foundation.Hash/CrcHelper.cs | 45 ++++++++++++++----------- 1 file changed, 26 insertions(+), 19 deletions(-) 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; + } + } }