CRC32 - 更改初始值
CRC32 - change initial value
我想用 Java 中的初始 CRC 值计算字节数组的 CRC32 值,与此 Python 脚本中相同:
import zlib
def getCrc32():
with open("test.py", mode='rb') as file:
fileContent = file.read()
crcVal = zlib.crc32(fileContent,10)
if __name__ == "__main__":
getCrc32()
但是在Java中,我不能用下面的代码得到相同的结果:
RandomAccessFile f = new RandomAccessFile("test.py", "r");
byte[] b = new byte[(int) f.length()];
f.readFully(b);
CRC32 c2 = new CRC32();
c2.update(10);
c2.update(b);
System.out.println((int) c2.getValue());
如何计算初始值为 Java 的 CRC32?
你不能,至少不能直接。 Java class 不提供设置当前 CRC 值的方法。 (reset()
方法应该为此接受一个参数,但可惜它没有。)
然而,可以导出将 CRC 设置为给定所需值的四个消息字节。你可以用这四个字节做一个 reset()
然后一个 update()
来将 CRC 设置为你想要的。 spoof code 可以为您做到这一点。
spoof 对此有点矫枉过正,但您可以从该代码中得出所需的内容。实际上你只需要 Ax + b,其中 A 是一个常数 32x32 位矩阵,x 是所需的 CRC,而 b 是一个 32 位常量,结果是要馈送的 32 位(四个字节)以获得所需的 CRC。矩阵乘法和向量加法以 2 为模完成,其中异或代替加法,而运算符代替乘法。
你没试过用Reflection设置CRC32实例的crc字段吗?这对我有用。
String input = "Hello World!";
String input2 = "I love you!";
CRC32 crc = new CRC32();
crc.update(input.getBytes());
System.out.println("input: " + input);
System.out.println("crc: " + crc.getValue());
CRC32 crc2 = new CRC32();
System.out.println("crc2: " + crc2.getValue());
try {
Field crcField = CRC32.class.getDeclaredField("crc");
final boolean accessible = crcField.isAccessible();
System.out.println("crc2 original accessible: " + accessible);
crcField.setAccessible(true);
System.out.println("crc2 accessible is set to " + crcField.isAccessible());
System.out.println("crc2 about to do reflection...");
crcField.setInt(crc2, (int) crc.getValue());
System.out.println("crc2 reflection is done.");
System.out.println("crc2: " + crc2.getValue());
System.out.println("crc2 current crc accessible: " + crcField.isAccessible());
System.out.println("crc2 accessible is being restored to " + accessible);
crcField.setAccessible(accessible);
System.out.println("crc2 current crc accessible: " + crcField.isAccessible());
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("input2: " + input2);
crc2.update(input2.getBytes());
System.out.println("crc2: " + crc2.getValue());
CRC32 crc3 = new CRC32();
String wholeInput = input + input2;
System.out.println("input + input2: " + wholeInput);
crc3.update((wholeInput).getBytes());
System.out.println("crc3: " + crc3.getValue());
我想用 Java 中的初始 CRC 值计算字节数组的 CRC32 值,与此 Python 脚本中相同:
import zlib
def getCrc32():
with open("test.py", mode='rb') as file:
fileContent = file.read()
crcVal = zlib.crc32(fileContent,10)
if __name__ == "__main__":
getCrc32()
但是在Java中,我不能用下面的代码得到相同的结果:
RandomAccessFile f = new RandomAccessFile("test.py", "r");
byte[] b = new byte[(int) f.length()];
f.readFully(b);
CRC32 c2 = new CRC32();
c2.update(10);
c2.update(b);
System.out.println((int) c2.getValue());
如何计算初始值为 Java 的 CRC32?
你不能,至少不能直接。 Java class 不提供设置当前 CRC 值的方法。 (reset()
方法应该为此接受一个参数,但可惜它没有。)
然而,可以导出将 CRC 设置为给定所需值的四个消息字节。你可以用这四个字节做一个 reset()
然后一个 update()
来将 CRC 设置为你想要的。 spoof code 可以为您做到这一点。
spoof 对此有点矫枉过正,但您可以从该代码中得出所需的内容。实际上你只需要 Ax + b,其中 A 是一个常数 32x32 位矩阵,x 是所需的 CRC,而 b 是一个 32 位常量,结果是要馈送的 32 位(四个字节)以获得所需的 CRC。矩阵乘法和向量加法以 2 为模完成,其中异或代替加法,而运算符代替乘法。
你没试过用Reflection设置CRC32实例的crc字段吗?这对我有用。
String input = "Hello World!";
String input2 = "I love you!";
CRC32 crc = new CRC32();
crc.update(input.getBytes());
System.out.println("input: " + input);
System.out.println("crc: " + crc.getValue());
CRC32 crc2 = new CRC32();
System.out.println("crc2: " + crc2.getValue());
try {
Field crcField = CRC32.class.getDeclaredField("crc");
final boolean accessible = crcField.isAccessible();
System.out.println("crc2 original accessible: " + accessible);
crcField.setAccessible(true);
System.out.println("crc2 accessible is set to " + crcField.isAccessible());
System.out.println("crc2 about to do reflection...");
crcField.setInt(crc2, (int) crc.getValue());
System.out.println("crc2 reflection is done.");
System.out.println("crc2: " + crc2.getValue());
System.out.println("crc2 current crc accessible: " + crcField.isAccessible());
System.out.println("crc2 accessible is being restored to " + accessible);
crcField.setAccessible(accessible);
System.out.println("crc2 current crc accessible: " + crcField.isAccessible());
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("input2: " + input2);
crc2.update(input2.getBytes());
System.out.println("crc2: " + crc2.getValue());
CRC32 crc3 = new CRC32();
String wholeInput = input + input2;
System.out.println("input + input2: " + wholeInput);
crc3.update((wholeInput).getBytes());
System.out.println("crc3: " + crc3.getValue());