文件同步

   内容涉及到Rsync算法,Adler32算法,MD5算法,内容就不再多说,直接上代码:

   1.类的目录图

wKiom1N2INKxN-6LAAD2E3SGxW0667.jpg2.


2.Rsync类:

package org.hadoop.rsync;
import org.hadoop.rsync.util.RsyncUtil;
/**
 *@author
 *@2014年5月16日
 *@e-mail:
 *主类
 */
public class Rsync {
    public static void main(String []args)throws Exception{
        doRsync("C:\\src.txt","C:\\target.txt");
    }
    public static void doRsync(String srcFileName,String targetName)throws Exception{
        RsyncUtil.applyPatch(srcFileName,targetName);
    }
}


3.RsyncUtil类:

package org.hadoop.rsync.util;
import org.hadoop.adler32.*;
import org.hadoop.md5.*;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hadoop.rsync.*;
/**
 *@author
 *@2014年5月16日
 *@e-mail:
 *工具类
 */
public class RsyncUtil {
                                                                                                                                                                                                                                                                                            
    /**
     * 计算文件的CheckSum列表
     * @param fileName
     * @return
     */
    public static Map<Long,List<Chunk>> calcCheckSumFromFile(String fileName){
        Map<Long,List<Chunk>> chunkMaps = new HashMap<Long,List<Chunk>>();
        try{
            File file = new File(fileName);
            long fileLength = file.length();
            long remainedLength = fileLength;
            int read = 0;
            long index = 0;//块号
            RandomAccessFile raf = new RandomAccessFile(fileName,"r");
            while(remainedLength > 0){
                read = (remainedLength < Constant.CHUNK_SIZE) ? (int)remainedLength:Constant.CHUNK_SIZE;
                byte []buffer = new byte[read];
                raf.read(buffer);
                Chunk chunk = calcCheckSum(buffer,read);
                chunk.setIndex(index++);
                //判断chunks中是否存在
                if(chunkMaps.containsKey(chunk.getWeakCheckSum())){
                    //如果存在,则iaru链表中
                    chunkMaps.get(chunk.getWeakCheckSum()).add(chunk);
                }else{
                    //如果不存在,则创建链表加入其中
                    List<Chunk> chunks = new ArrayList<Chunk>();
                    chunks.add(chunk);
                    chunkMaps.put(new Long(chunk.getWeakCheckSum()),chunks);
                }//chunkMaps.put(new Long(Chunk.getWeakCheckSum()).chunks);
                remainedLength -= read;
            }
            raf.close();
        }catch(Exception e){
            e.printStackTrace();
        }
        return chunkMaps;
    }
                                                                                                                                                                                                                                                                                            
    /**
     * 计算每块的checksum
     * @param buffer
     * @param length
     * @return
     */
    private static Chunk calcCheckSum(byte[] buffer, int length){
        Chunk chunk = new Chunk();
        chunk.setWeakCheckSum(Adler32.adler32(buffer,0,length));
        chunk.setStrongCheckSum(MD5.getMD5(buffer));
        chunk.setLength(length);
        return chunk;
    }
                                                                                                                                                                                                                                                                                            
    /**
     * 根据传入的字节数组去匹配,如果匹配到则返回该chunk,否则为空
     * @param chunkMaps
     * @param datas
     * @return
     */
    public static Chunk match(Map<Long,List<Chunk>> chunkMaps,byte[]datas){
        Long weakChecksum = new Long(Adler32.adler32(datas));
        if(chunkMaps.containsKey(weakChecksum)){
            for(Chunk chunk:chunkMaps.get(weakChecksum)){
                if(MD5.getMD5(datas).equals(chunk.getStrongCheckSum())){
                    return chunk;
                }
            }
        }
        return null;
    }
                                                                                                                                                                                                                                                                                            
    /**
     * 读取下一个block
     * @param raf
     * @param remainedLength
     * @return
     * @throws Exception
     */
    public static byte[] readNextBlock(RandomAccessFile raf,long remainedLength)throws Exception{
        int bufferSize = (remainedLength < Constant.CHUNK_SIZE) ? (int) remainedLength:Constant.CHUNK_SIZE;
        byte[] buffer = new byte[bufferSize];
        raf.read(buffer);
        return buffer;
    }
                                                                                                                                                                                                                                                                                            
    /**
     * 读取下一个byte
     * @param raf
     * @param block
     * @return
     * @throws Exception
     */
    public static byte[]readNextByte(RandomAccessFile raf,byte[] block)throws Exception{
        byte [] next = new byte[1];
        raf.read(next);
        for(int i = 0; i < block.length - 1; i++){
            block[i] = block[i + 1];
        }
        block[block.length - 1] = next[0];
        return block;
    }
                                                                                                                                                                                                                                                                                            
    /**
     * 创建补丁
     * @param srcFileName
     * @param targetFileName
     * @return
     * @throws Exception
     */
    public static Patch createPatch(String srcFileName,String targetFileName)throws Exception{
        Map<Long,List<Chunk>> chunkMaps = calcCheckSumFromFile(targetFileName);
        Patch patch = new Patch();
        File file = new File(srcFileName);
        RandomAccessFile raf = new RandomAccessFile(file,"r");
        long fileLength = file.length();
        long remainedLength = fileLength;
        byte [] bytes = {};
        Chunk chunk = null;
        List<Byte> diffBytes = new ArrayList<Byte>();
        boolean nextBlock = true;
                                                                                                                                                                                                                                                                                                
        while(remainedLength > 0){
            if(nextBlock){
                bytes = readNextBlock(raf,remainedLength);
                remainedLength -= bytes.length;
            }else{
                bytes = readNextByte(raf,bytes);
                remainedLength--;
            }
            //判断是否匹配
            chunk = match(chunkMaps,bytes);
            if(chunk != null){
                //匹配的chunk之间存在differ_data,先将它加进Patch
                if(diffBytes.size() > 0){
                    patch.add(diffBytes);
                    diffBytes = new ArrayList<Byte>();//重新创建一个空的differ bytes
                }
                patch.add(chunk);
                nextBlock = true;
            }else{
                //将最左的byte保存,不能读block 只能读下一个byte
                diffBytes.add(bytes[0]);
                nextBlock = false;
            }
        }
        //最后一个block没有匹配上,需要把bytes中的剩余数据加入到diffBytes中,0已经加入了
        if(chunk == null){
            for(int i = 0; i < bytes.length; i++){
                diffBytes.add(bytes[i]);
            }
        }
        patch.add(diffBytes);
        raf.close();
        return patch;
    }
                                                                                                                                                                                                                                                                                            
    public static void applyPatch(String srcFileName,String targetName)throws Exception{
        Patch patch = createPatch(srcFileName,targetName);
        RandomAccessFile srcFile = new RandomAccessFile(srcFileName,"r");
        String[] strs = srcFileName.split("[.]");
        String str = "";
        if(strs.length > 1){
            str = strs[1];
        }
        RandomAccessFile targetFile = new RandomAccessFile(srcFileName + "_path." + str,"rw");
        long srcFileLength = srcFile.length();
        //遍历补丁
        for(PatchPart part:patch.getParts()){
            if(part instanceof PatchPartData){
                targetFile.write(((PatchPartData)part).getDatas());
            }else{
                PatchPartChunk chunkPart = (PatchPartChunk)part;
                long off = chunkPart.getIndex()*Constant.CHUNK_SIZE;
                long remainedFileLength = srcFileLength - off;
                                                                                                                                                                                                                                                                                                        
                int length = remainedFileLength<Constant.CHUNK_SIZE?(int)remainedFileLength:Constant.CHUNK_SIZE;
                byte[] bytes = new byte[length];
                                                                                                                                                                                                                                                                                                        
                srcFile.seek(off);
                srcFile.read(bytes);
                targetFile.write(bytes);
            }
        }
        srcFile.close();
        targetFile.close();
    }
}


4.Chunk类:

package org.hadoop.rsync;
/**
 *@author
 *@2014年5月16日
 *@e-mail:
 */
public class Chunk {
    private long index;//块号
    private int weakCheckSum;
    private String strongCheckSum;
    private int length;
                                                                                                                                                                                                                                                                                     
    public long getIndex() {
        return index;
    }
    public void setIndex(long index) {
        this.index = index;
    }
                                                                                                                                                                                                                                                                                     
    public int getWeakCheckSum() {
        return weakCheckSum;
    }
    public void setWeakCheckSum(int weakCheckSum) {
        this.weakCheckSum = weakCheckSum;
    }
                                                                                                                                                                                                                                                                                     
    public String getStrongCheckSum() {
        return strongCheckSum;
    }
    public void setStrongCheckSum(String strongCheckSum) {
        this.strongCheckSum = strongCheckSum;
    }
                                                                                                                                                                                                                                                                                     
    public int getLength() {
        return length;
    }
    public void setLength(int length) {
        this.length = length;
    }
}


5.Patch类:

package org.hadoop.rsync;
import java.util.ArrayList;
import java.util.List;
/**
 *@author
 *@2014年5月16日
 *抽象的补丁类,源文件 +补丁 = 目标文件
 */
public class Patch {
    private List<PatchPart> parts = new ArrayList<PatchPart>();
    public void add(List<Byte> datas){
        parts.add(new PatchPartData(datas));
    }
                                                                                                                                                                                                                                                                               
    public void add(Chunk chunk){
        parts.add(new PatchPartChunk(chunk.getIndex()));
    }
                                                                                                                                                                                                                                                                               
    public List<PatchPart>getParts(){
        return parts;
    }
    public void setParts(List<PatchPart> parts) {
        this.parts = parts;
    }
}



注: PatchPart类设成抽象类,是因为下面有PatchPartChunk类与PatchPartData类继承了它.


6.PatchPart类:

package org.hadoop.rsync;
/**
 *@author
 *@2014年5月16日
 *Patch内容抽象类,因为有2种不同的内容,对于已经存在的内容
 *我们只需要记录index,不存在的内容,我们需要存bytes数据
 */
public abstract class  PatchPart {
}


7.PatchPartChunk类:

package org.hadoop.rsync;
/**
 *@author
 *@2014年5月16日
 *匹配的chunk,只需要记录index;
 */
public class PatchPartChunk extends PatchPart{
    private long index;
    public long getIndex() {
        return index;
    }
    public void setIndex(long index) {
        this.index = index;
    }
                                                                                                                                                                                                      
    public PatchPartChunk(long index){
        this.index = index;
    }
}


8.PatchPartData类:

package org.hadoop.rsync;
import java.util.List;
/**
 *@author
 *@2014年5月16日
 *@e-mail:
 */
public class PatchPartData extends PatchPart{
    private byte[] datas;
    public byte[] getDatas() {
        return datas;
    }
    public void setDatas(byte[] datas) {
        this.datas = datas;
    }
    public PatchPartData(List<Byte> datas){
        this.datas = new byte[datas.size()];
        for(int i = 0; i < datas.size(); i++){
            this.datas[i] = datas.get(i);
        }
    }
}


9.Constant类:

package org.hadoop.rsync;
/**
 *@author
 *@2014年5月16日
 *@e-mail:
 */
public class Constant {
    //块大小
    public final static int CHUNK_SIZE = 512;
}


10.Adler32算法:

package org.hadoop.adler32;
/**
 * @author: xiehui
 * @mailto:
 * @version 2013-12-3
 * @see http://tools.ietf.org/html/rfc3309
 * Adler32算法:
 *      A(1, n) = 1 + D1 + D2 + ... + Dn (mod 65521)
 *     A(2, n+1) = 1+ D2 + D3 +.....+ (Dn+1)  (mod 65521)
 *     B(1,n) =    (1 + D1) + (1 + D1 + D2) + ... + (1 + D1 + D2 + ... + Dn) (mod 65521)
 *          = n×D1 + (n1)×D2 + (n2)×D3 + ... + Dn + n (mod 65521)
 *      B(2,n+1) = (1 + D2) + (1 + D2 + D3) + ... + (1 + D2 + D3 + ... + Dn+1) (mod 65521)
 *     Adler-32(D) = B × 65536 + A
 *   
 * 
 */
public class Adler32 {
    /*
     * the largest prime number smaller than 216
     */
    protected static final int MOD_ADLER = 65521;
    /**
     * @param datas  待计算的数据块
     * @param offset   待计算的偏移
     * @param length 待计算的长度
     * @return  校验和
     */
    public static int adler32( byte[] datas , int offset , int length ){
        int A = 1;
        int B = 0;
        for( int i = offset ; i< offset + length ; i++ ){
            //1. 计算A
            A += datas[i];
            if( A >= MOD_ADLER ){
                A -= MOD_ADLER;
            }
            //2. 计算B
            B += A;
            if( B >= MOD_ADLER){
                B -= MOD_ADLER;
            }
        }
        //3. 返回校验和
        return B << 16 | A;
    }
                                                                                                                           
    /**
     *  Adler-32 核心算法在于计算下一块的checksum复杂度为 O( 1 )
     * @param oldAdler32 初始chunksum
     * @param chunkSize  块大小
     * @param preByte  前一个字节
     * @param nextByte 后一个字节
     * @return
     */
    public static int nextAdler32(int oldAdler32 , int chunkSize, byte preByte , byte nextByte ){
        int oldA = oldAdler32 & 0xFFFF ;
        int oldB = (oldAdler32 >>> 16) & 0xFFFF;
        int A = oldA - preByte + nextByte;  //向右移动一字节
        int B = oldB - preByte *  (chunkSize ) -1 + A  ;
        return (B << 16) | A;
    }
                                                                                                                           
    /**
     *
     * @param datas 待加密数据块
     * @return  校验和
     */
    public static int adler32(byte[] datas){
        return adler32( datas , 0 , datas.length );
    } 
}

11.MD5算法:

package org.hadoop.md5;
/**
 * @author: xiehui
 * @mailto:
 * @version 2013-12-3
 * @see http://tools.ietf.org/html/rfc1321
 * MD5 算法
 */
public class MD5 {
                                                                                                                   
    public static final int MOD_MD5 = 56;
                                                                                                                   
    public static final int BLOCK_SIZE = 64;
                                                                                                                   
    /** Step 3.  Initialize MD Buffer
     *  A four-word buffer (A,B,C,D) is used to compute the message digest.
     *  Here each of A, B, C, D is a 32-bit register. These registers are
     *  initialized to the following values in hexadecimal, low-order bytes first):
     *  word A: 01 23 45 67
     *  word B: 89 ab cd ef
     *  word C: fe dc ba 98
     *  word D: 76 54 32 10
     */
    public static long[] input ;
                                                                                                                   
    //转换时移位个数,来源于算法定义
    public static final int  S11 = 7;
    public static final int S12 = 12;
    public static final int S13 = 17;
    public static final int S14 = 22;
    public static final int S21 = 5;
    public static final int S22 = 9;
    public static final int S23 = 14;
    public static final int S24 = 20;
    public static final int S31 = 4;
    public static final int S32 = 11;
    public static final int S33 = 16;
    public static final int S34 = 23;
    public static final int S41 =6;
    public static final int S42 = 10;
    public static final int S43 = 15;
    public static final int S44 = 21;
                                                                                                                   
    private static byte[] output = new byte[16];
    public static void init(){
        input = new long[4];
        input[0] =0x67452301L;
        input[1]=0xEFCDAB89L;
        input[2]=0x98BADCFEL;
        input[3]=0x10325476L;
        output=new byte[16];
    }
    public static String getMD5(byte[] datas) {
        init();//每次调用先初始化;
        md5Outer(transformInput(datas,datas.length));
        encode(output,input,16);
        String digestHexStr = "";
        for (int i = 0; i < 16; i++) {
              digestHexStr += byteHEX(output[i]);
        }
        return digestHexStr;
  }
                                                                                                                   
    /**
     * Step 1. Append Padding Bits
       The message is "padded" (extended) so that its length (in bits) is
       congruent to 448, modulo 512. That is, the message is extended so
       that it is just 64 bits shy of being a multiple of 512 bits long.
       Padding is always performed, even if the length of the message is
       already congruent to 448, modulo 512.
       Padding is performed as follows: a single "1" bit is appended to the
       message, and then "0" bits are appended so that the length in bits of
       the padded message becomes congruent to 448, modulo 512. In all, at
       least one bit and at most 512 bits are appended.
     */
                                                                                                                   
    public  static byte[] paddingBits(byte[] bits){
        int mod = bits.length % BLOCK_SIZE;
        byte[] values;
        if( mod == MOD_MD5){
            values = new byte[bits.length+BLOCK_SIZE];
            values[bits.length] = (byte) -128; // -128 对应二进制位 10000000
            System.arraycopy(bits, 0, values, 0,bits.length);
        }else{
            values = new byte[bits.length+(MOD_MD5 - mod)];
            values[bits.length] =  (byte) -128;
            System.arraycopy(bits, 0, values, 0, bits.length);
        }
        return values;
    }
                                                                                                                   
    /**
     * Step 2. Append Length
       A 64-bit representation of b (the length of the message before the
       padding bits were added) is appended to the result of the previous
       step. In the unlikely event that b is greater than 2^64, then only
       the low-order 64 bits of b are used. (These bits are appended as two
       32-bit words and appended low-order word first in accordance with the
       previous conventions.)
       At this point the resulting message (after padding with bits and with
       b) has a length that is an exact multiple of 512 bits. Equivalently,
       this message has a length that is an exact multiple of 16 (32-bit)
       words. Let M[0 ... N-1] denote the words of the resulting message,
       where N is a multiple of 16.
                                                                                                                      
       @param bits padding 之后的数据
       @param srcLength 原始长度
     */
    public  static byte[] appendLength(byte[] bits,long srcLength){
                                                                                                                       
        byte[] temp = new byte[8];
        for(int i = 0 ; i < temp.length ; i++){
            temp[i]= (byte) ((srcLength*8)>>>i*8);
        }
        byte[] values = new byte[bits.length+temp.length];
        System.arraycopy(bits, 0, values, 0, bits.length);
        System.arraycopy(temp, 0, values,bits.length,temp.length);
        return values;
    }
    /**
     * 将原始输入字节流转化为MD5处理的字节流
     * @param input  输入数据
     * @param srcLength 数据原始长度
     * @return
     */
    public static byte[] transformInput(byte[] input,int srcLength){
        byte[] output = appendLength(paddingBits(input),srcLength);
        return output;
    }
                                                                                                                   
    /**
     *  1.先进行分块 512 位为一个block
     *  2. 然后将block 再分为 16个子块 每个块32位
     * @param bits  已经处理过的数据
     */
    public static void md5Outer(byte[] bits){
        for(int i = 0 ;  i < bits.length ; i+=64){
            long [] x = new long[16];
            byte[] temp = new byte[64];
            System.arraycopy(bits, i, temp, 0, 64);
            Decode(x,temp,64);
            md5Inner(x);
        }
    }
                                                                                                                   
    private static long byte2long(byte b){
        return b < 0 ? b&0x7F+128 : b;
    }
                                                                                                                   
    private static  void Decode (long[] output, byte[] input, int len) {
          int i, j;
          for (i = 0, j = 0; j < len; i++, j += 4)
                output[i] = byte2long(input[j]) |
                    (byte2long(input[j + 1]) << 8) |
                    (byte2long(input[j + 2]) << 16) |
                    (byte2long(input[j + 3]) << 24);
          return;
    }
                                                                                                                  
                                                                                                                   
    private static void encode (byte[] output, long[] input, int len) {
        int i, j;
        for (i = 0, j = 0; j < len; i++, j += 4) {
              output[j] = (byte)(input[i] & 0xffL);
              output[j + 1] = (byte)((input[i] >>> 8) & 0xffL);
              output[j + 2] = (byte)((input[i] >>> 16) & 0xffL);
              output[j + 3] = (byte)((input[i] >>> 24) & 0xffL);
        }
  }
                                                                                                                   
    /**
     * 用来把一个byte类型的数转换成十六进制的ASCII表示
     * @param ib
     * @return
     */
    public static String byteHEX(byte b) {
        char[] Digit = { '0','1','2','3','4','5','6','7','8','9',
        'A','B','C','D','E','F' };
        char [] ob = new char[2];
        ob[0] = Digit[(b >>> 4) & 0X0F];
        ob[1] = Digit[b & 0X0F];
        String s = new String(ob);
        return s;
  }
                                                                                                                   
    /**
     *
    AA =A ;
    BB = B;
    CC = C;
    DD = D;
    Round 1.
    Let [abcd k s i] denote the operation
         a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s).
     Do the following 16 operations.
    [ABCD  0  7  1]  [DABC  1 12  2]  [CDAB  2 17  3]  [BCDA  3 22  4]
    [ABCD  4  7  5]  [DABC  5 12  6]  [CDAB  6 17  7]  [BCDA  7 22  8]
    [ABCD  8  7  9]  [DABC  9 12 10]  [CDAB 10 17 11]  [BCDA 11 22 12]
    [ABCD 12  7 13]  [DABC 13 12 14]  [CDAB 14 17 15]  [BCDA 15 22 16]
     Round 2.
    Let [abcd k s i] denote the operation
         a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s).
    Do the following 16 operations.
    [ABCD  1  5 17]  [DABC  6  9 18]  [CDAB 11 14 19]  [BCDA  0 20 20]
    [ABCD  5  5 21]  [DABC 10  9 22]  [CDAB 15 14 23]  [BCDA  4 20 24]
    [ABCD  9  5 25]  [DABC 14  9 26]  [CDAB  3 14 27]  [BCDA  8 20 28]
    [ABCD 13  5 29]  [DABC  2  9 30]  [CDAB  7 14 31]  [BCDA 12 20 32]
    Round 3.
    Let [abcd k s t] denote the operation
         a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s).
    Do the following 16 operations.
    [ABCD  5  4 33]  [DABC  8 11 34]  [CDAB 11 16 35]  [BCDA 14 23 36]
    [ABCD  1  4 37]  [DABC  4 11 38]  [CDAB  7 16 39]  [BCDA 10 23 40]
    [ABCD 13  4 41]  [DABC  0 11 42]  [CDAB  3 16 43]  [BCDA  6 23 44]
    [ABCD  9  4 45]  [DABC 12 11 46]  [CDAB 15 16 47]  [BCDA  2 23 48]
     Round 4.
    Let [abcd k s t] denote the operation
         a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s).
    Do the following 16 operations.
    [ABCD  0  6 49]  [DABC  7 10 50]  [CDAB 14 15 51]  [BCDA  5 21 52]
    [ABCD 12  6 53]  [DABC  3 10 54]  [CDAB 10 15 55]  [BCDA  1 21 56]
    [ABCD  8  6 57]  [DABC 15 10 58]  [CDAB  6 15 59]  [BCDA 13 21 60]
    [ABCD  4  6 61]  [DABC 11 10 62]  [CDAB  2 15 63]  [BCDA  9 21 64]
                                                                                                                  
     A = A + AA
     B = B + BB
     C = C + CC
     D = D + DD
     */
    public static void md5Inner(long x[]){
        long a = input[0] ;
        long b = input[1] ;
        long c =  input[2];
        long d = input[3];
                                                                                                                       
        //第一轮
         a = FF (a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */
         d = FF (d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */
         c = FF (c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */
         b = FF (b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */
         a = FF (a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */
         d = FF (d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */
         c = FF (c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */
         b = FF (b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */
         a = FF (a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */
         d = FF (d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */
         c = FF (c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */
         b = FF (b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */
         a = FF (a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */
         d = FF (d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */
         c = FF (c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */
         b = FF (b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */
         //第二轮
         a = GG (a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */
         d = GG (d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */
         c = GG (c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */
         b = GG (b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */
         a = GG (a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */
         d = GG (d, a, b, c, x[10], S22, 0x2441453L); /* 22 */
         c = GG (c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */
         b = GG (b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */
         a = GG (a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */
         d = GG (d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */
         c = GG (c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */
         b = GG (b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */
         a = GG (a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */
         d = GG (d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */
         c = GG (c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */
         b = GG (b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */
         //第三轮
         a = HH (a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */
         d = HH (d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */
         c = HH (c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */
         b = HH (b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */
         a = HH (a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */
         d = HH (d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */
         c = HH (c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */
         b = HH (b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */
         a = HH (a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */
         d = HH (d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */
         c = HH (c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */
         b = HH (b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */
         a = HH (a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */
         d = HH (d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */
         c = HH (c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */
         b = HH (b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */
         //第四轮
         a = II (a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */
         d = II (d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */
         c = II (c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */
         b = II (b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */
         a = II (a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */
         d = II (d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */
         c = II (c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */
         b = II (b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */
         a = II (a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */
         d = II (d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */
         c = II (c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */
         b = II (b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */
         a = II (a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */
         d = II (d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */
         c = II (c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */
         b = II (b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */
                                                                                                                        
         input[0] += a;
         input[1] += b;
         input[2] += c;
         input[3] += d;
    }
                                                                                                                   
                                                                                                                   
    /**
     *   第一轮
     *   a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s).
     */
    private static long FF( long a , long b , long c , long d , long k , long s , long i ){
        a += F(b,c,d)+k+i;
        a = ((int)a <<s)| (int)a>>>(32-s);
        a +=b;
        return a;
    }
                                                                                                                   
    /**
     *  第二轮
     *  a = b + ((a + G(b,c,d) + X[k] + T) <<< s).
     */
    private static long GG( long a , long b , long c , long d , long k , long s , long i ){
        a += G(b,c,d)+k+i;
        a = ((int)a <<s)| (int)a>>>(32-s);
        a +=b;
        return a;
    }
                                                                                                                   
    /**
     *  第三轮
     *  a = b + ((a + H(b,c,d) + X[k] + T) <<< s)
     */
    private static  long HH( long a , long b , long c , long d , long k , long s , long i ){
        a += H(b,c,d)+k+i;
        a = ((int)a <<s)| (int)a>>>(32-s);
        a +=b;
        return a;
    }
                                                                                                                   
    /**
     * 第四轮
     * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
     */
    private static long II( long a , long b , long c , long d , long k , long s , long i ){
        a += I(b,c,d)+k+i;
        a = ((int)a <<s)| (int)a>>>(32-s);
        a +=b;
        return a;
    }
                                                                                                                   
                                                                                                                   
    //Four auxiliary functions
    /**
     *  F(X,Y,Z) = XY v not(X) Z
     */
    private static long F( long x , long y , long z ){
        return ( x & y ) | ( ( ~x ) & z );
    }
                                                                                                                   
    /**
     *  G(X,Y,Z) = XZ v Y not(Z)
     */
    private static long G( long x , long y , long z ){
        return ( x & z ) | ( y & ( ~z ) );
    }
                                                                                                                   
    /**
     *  H(X,Y,Z) = X xor Y xor Z
     */
    private static long H( long x , long y , long z ){
        return x ^ y ^ z;
    }
                                                                                                                   
    /**
     *  I(X,Y,Z) = Y xor (X v not(Z))
     */
    private static long I( long x , long y , long z){
        return y ^ ( x | ( ~z ));
    }
                                                                                                                   
}



        这一段时间参加谢老师(非常牛逼)的hadoop集训课程,才有这样的成果,懂了文件同步,在这里非常非常的感谢他!

        谢谢谢老师!!!

你可能感兴趣的:(同步文件)