基于rsync同步算法的文件同步系统JAVA实现(二)——校验码的生成
2013-08-23 21:07
746 查看
作用:
分析差异数据块过程中需要不完整文件各个数据块的两种校验:滚动校验和md4校验,先对完整文件的各个分块依次进行滚动校验,若相同再进行md4校验,若再次相同说明数据块匹配,否则不匹配,在文件中向后移动一个字节形成的新分块进行校验(利用滚动校验的特性可以很快完成)。核心算法1-滚动校验(参考rsync源码,并作了少量类型修改(unsigned转long)):
弱校验,优点是速度快(但不能保证唯一性),两个校验函数,一种是根据一整个数据块生成校验码,另一种是根据前一个数据块已知的校验码和新的字节信息产生校验码(快)。源码:
/** * 非递推滚动校验 a simple 32 bit checksum that can be upadted from either end * (inspired by Mark Adler's Adler-32 checksum) * * @param bs * @param len * @return */ public static long checkSum_Adler32(byte[] buf, int len) { int i; long s1, s2; // for (i = 0; i < len ; i++) { // if (buf[i] < 0) { // buf[i] = (byte) -buf[i]; // } // } s1 = s2 = 0; for (i = 0; i < (len - 4); i += 4) { s2 += 4 * (s1 + buf[i]) + 3 * buf[i + 1] + 2 * buf[i + 2] + buf[i + 3]; s1 += (buf[i + 0] + buf[i + 1] + buf[i + 2] + buf[i + 3]); } for (; i < len; i++) { s1 += (buf[i]); s2 += s1; } return (s1 & 0xffff) + ((s2 & 0xffff) << 16); } /** * 递推滚动校验 adler32_checksum(X0, ..., Xn), X0, Xn+1 ----> adler32_checksum(X1, * ..., Xn+1) where csum is adler32_checksum(X0, ..., Xn), c1 is X0, c2 is * Xn+1 */ public static long adler32_rolling_checksum(long csum, int len, byte c1, byte c2) { // if (c1 < 0) { // c1 = (byte) -c1; // } // if (c2 < 0) { // c2 = (byte) -c2; // } long s1, s2; s1 = (csum & 0xffff); s2 = (csum >> 16); s1 -= (c1 - c2); s2 -= (len * c1 - s1); return (s1 & 0xffff) + ((s2 & 0xffff) << 16); }
核心算法2-md4(最好是md5)校验:
强校验,可以保证唯一性,但是速度慢些。源码略
注意细节:
检验码最终需要转换成字节流,需要给出起始和终止信号。部分整合源码:
public void writeCheckSumFile(InputStream in, OutputStream outStreamCheckSumFile) throws IOException { BufferedInputStream inStreamHalfFile = new BufferedInputStream(in); byte[] buffer = new byte[BLOCKSIZE]; int amount = 0; while ((amount = inStreamHalfFile.read(buffer)) != -1) { sendCheckSumToFile(buffer, outStreamCheckSumFile, amount); } byte end[] = new byte[24]; Arrays.fill(end, (byte) -1); outStreamCheckSumFile.write(end); } public void sendCheckSumToFile(byte[] buffer, OutputStream outputStream, int amount) throws IOException { long sum1 = SumChecking.checkSum_Adler32(buffer, amount); byte sum2[] = Md4Checking.mdfour(buffer); outputStream.write(DataConvertUtils.long2bytes(sum1)); outputStream.write(sum2); } public void readCheckSumFile(String filein) throws IOException { BufferedInputStream fileInputStream = new BufferedInputStream( new FileInputStream(filein)); byte[] buffer1 = new byte[8]; byte[] buffer2 = new byte[16]; while ((fileInputStream.read(buffer1)) != -1) { fileInputStream.read(buffer2); System.out.print(DataConvertUtils.bytes2long(buffer1) + ","); //$NON-NLS-1$ System.out.print(Md4Checking.toHexString(buffer2) + ";"); //$NON-NLS-1$ System.out.println(); } fileInputStream.close(); }
相关文章推荐
- 基于rsync同步算法的文件同步系统JAVA实现(三)——校验码哈希表的建立
- 基于rsync同步算法的文件同步系统JAVA实现(一)——项目介绍
- 基于rsync同步算法的文件同步系统JAVA实现(四)——分析并发送不匹配数据块
- 基于rsync同步算法的文件同步系统JAVA实现(一)——项目介绍
- 基于rsync同步算法的文件同步系统JAVA实现(五)—— 重组数据块
- java开发系统内核:实现基于FAT12文件系统的dir命令
- Rsync实现Windows系统与Linux文件同步
- Rsync实现文件同步的算法(转载)
- linux系统中rsync+inotify实现服务器之间文件实时同步
- linux下基于rsync + find命令实现文件同步机制
- 基于差异的文件同步算法-The rsync algorithm
- 基于cron、rsync和ssh免密码登录实现Linux系统间自动同步~
- 基于差异的文件同步算法-The rsync algorithm
- linux系统中rsync+inotify实现服务器之间文件实时同步
- 基于rsync和inotify实现web网站文件的同步,并基于IPTABLES做用户限制 推荐
- 基于rsync+inotify实现文件实时同步
- Centos7.0系统下Rsync+sersync实现多文件数据实时增量同步 推荐
- rsync实现网站的备份,文件的同步,不同系统的文件的同步,如果是windows的话,需要windows版本cwrsync【文件从本地上传到linux服务器有什么更好的工具?】
- linux系统中rsync+inotify实现服务器之间文件实时同步
- linux系统使用Rsync+sersync实现文件实时同步