Java 实现校验和(Checksum)
本文简要解释什么是校验和以及如何在java中计算校验和。
1. 校验和及实现算法
校验和是指传输位数的累加,当传输结束时,接收者可以根据这个数值判断是否接到了所有的数据。如果数值匹配,那么说明传送已经完成。通常用来在通信中,尤其是远距离通信中保证数据的完整性和准确性。简言之,校验和是二进制数据流的迷你表示。
在网络编程中通常用于检查信息是否完整接收,在接收到新消息时,可以重新计算校验和并与接收到的校验和进行比较,以确保没有丢失任何字节位。此外,它们还可以用于文件管理,例如,比较文件或检测更改。
常用创建校验和的算法有Adler32 和 CRC32。这些算法的工作原理是将一系列数据或字节转换成更小的字母和数字序列。它们被设计成输入中的任何微小变化都会导致计算出的校验和大不相同。
本文介绍Java支持的CRC32算法。需要指出的是CRC32算法用于计算校验和非常有用,但不建议用于摘要算法,如密码摘要。
2. CRC32算法示例
2.1 求字符串或字节数组校验和
首先需要获得需要计算校验和的输入,如何是字符串,则需要调用getBytes()
获取字节数组:
String test = "test";
byte[] bytes = test.getBytes();
接下来通过字节数组计算校验和:
public static long getCRC32Checksum(byte[] bytes) {
Checksum crc32 = new CRC32();
crc32.update(bytes, 0, bytes.length);
return crc32.getValue();
}
这里使用java内置的CRC32类。实例化之后使用update方法,传入字节数组计算校验和。简单地说,update方法将替换CRC32对象所保存的字节,这有助于代码重用并消除创建校验和新实例的需要。CRC32类提供了一些被重写的方法,用于替换整个字节数组或其中的几个字节。最后通过getValue方法返回校验和。
2.2 求输入流校验和
当处理较大数据集时,上述方法因加载所有数据至内存导致效率低下。
如果可以获取InputStream,可以使用CheckedInputStream 类创建创建校验和。通过使用这种方法,我们可以定义一次处理多少字节。
下面例子处理给定一次那些处理字节的数量,直到流结束:
public static long getChecksumCRC32(InputStream stream, int bufferSize)
throws IOException {
CheckedInputStream checkedInputStream = new CheckedInputStream(stream, new CRC32());
byte[] buffer = new byte[bufferSize];
while (checkedInputStream.read(buffer, 0, buffer.length) >= 0) {}
return checkedInputStream.getChecksum().getValue();
}
3. 总结
本文我们介绍了校验和的概念,以及如何使用Java CRC32类计算字节数组或输入流(InputStream)的校验和。
本文参考链接:https://blog.csdn.net/neweastsun/article/details/108592314