TEA算法多语言实现——Java

来源:互联网 发布:淘宝号怎么会被冻结 编辑:程序博客网 时间:2024/06/05 05:16
主要分为两部分  加解密部分和编解码部分涉及两个文件1,tea.java 2,hex2byte.java/******************************************tea.java*****************************/package javaTEA;import java.io.UnsupportedEncodingException;public class tea {      private static int n=6;//密钥生成参数之一 从原始密钥字符串第 n位生成加密密钥    /**  * 原始加密函数  * @param v长度为2个32位数据  * @param k 加密密钥 为4个 32位数据  * @param rounds 加密轮数 16或32  * @return 加密后密文数据 两个32位数据  */ private static int[] en(int[] v,int[] k,int rounds){        int y=v[0],z=v[1],sum=0,delta=0x9E3779B9,                a=k[0],b=k[1],c=k[2],d=k[3];        int[] o=new int[2];        while(rounds-->0){            sum+=delta;            y+=((z << 4)+a)^(z+sum)^((z >>> 5)+b);            z+=((y << 4)+c)^(y+sum)^((y >>> 5)+d);                 }        o[0]=y;        o[1]=z;        return o;    } /**  * 原始解密函数  * @param v长度为2个32位数据  * @param k 加密密钥 为4个 32位数据  * @param rounds 加密轮数 16或32  * @return 解密后密文数据 两个32位数据  */    private static int[] de(int[] v,int[] k,int rounds){        int y=v[0],z=v[1],sum=0,                delta=0x9E3779B9,a=k[0],b=k[1],c=k[2],d=k[3];        if(rounds==32)            sum=0xc6ef3720;        else            sum=0xe3779b90;        int[] o=new int[2];        while(rounds-->0){            z-=((y << 4)+c)^(y+sum)^((y >>> 5)+d);            y-=((z << 4)+a)^(z+sum)^((z >>> 5)+b);            sum-=delta;        }        o[0]=y;        o[1]=z;        return o;    }    /**     * 将byte数组使用“:”相连成字符串     * @param a 待处理byte数组     * @return 处理后String     */    /*private static String byte2String(byte[] a){     String byteStr = new String();     for(int i=0;i<a.length;i++)     {      byteStr+=String.valueOf(a[i]);      if(i!=a.length-1)         byteStr+=":";     }     return byteStr;    }*/    /**     * 加如标识符函数,在经过加密后的密文前8byte 加入标识符     * @param orignal 需要加入标识符的原始密文bye[]数组     * @return 经过加入标识符后的密文     */    private static byte[] flag(byte[] orignal){     byte[] o=new byte[orignal.length+8];     byte[] flag=new byte[]{0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d};     System.arraycopy(flag, 0, o, 0, flag.length);     System.arraycopy(orignal, 0, o, flag.length, orignal.length);     return o;         }   /**    * 去除表示符函数    * @param orignal 需要进行处理的原始密文    * @return 去除标识符的密文    */    private static byte[] unflag(byte[] orignal){     byte[] o=new byte[orignal.length-8];      System.arraycopy(orignal, 8, o, 0, orignal.length-8);     return o;         }  /**   * 表示符比较函数 鉴定一个字符串是否含有标识符   * @param content 需要进行鉴定的字符串   * @return 返回1 则代表含有相同的标识符 否则表示和预定义的标识符不同   */      private static int flag_compare(byte[] content){       byte[] flag=new byte[]{0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d};        int i;        for(i=0;i<8;i++)     {     if(content[i]!=flag[i])     return 0;     }        return 1;        }      /**      * 经过封装后的加密函数      * @param content byte[] 明文byte数组      * @param key byte[] 密钥bate[]数组      * @return byte[] 经过加密且含有标识符的密文byte数组      */     public static byte[] encrypt(byte[] content, byte[] key,int rounds) {         if (content == null || key == null || content.length == 0 ||             key.length == 0) {             return null;         }         byte[] result = null;         int resultLength = content.length;         int mol = resultLength % 8; //         if (mol != 0) {             resultLength = resultLength + 8 - mol; //计算 密文长度         }         int[] k = validateKey3(key); // 设置密钥         int[] v = new int[2];         int[] o = null;         result = new byte[resultLength];         int convertTimes = resultLength - 8; //对前 n*8byte 加密         int next = 0;         int times = 0;         // 分块进行加密         for (; times < convertTimes; times += 8) {             next = times + 4;             v[0] = byte2int(content, times);             v[1] = byte2int(content, next);             o = en(v, k,rounds);             int2byte(o[0], result, times);             int2byte(o[1], result, next);         }         next = times + 4;         if (mol != 0) { // 最后8byte加密             byte[] tmp = new byte[8];             System.arraycopy(content, times, tmp, 0, mol);//不满则补0             v[0] = byte2int(tmp, 0);             v[1] = byte2int(tmp, 4);             o = en(v, k,rounds);             int2byte(o[0], result, times);             int2byte(o[1], result, next);         }         else {             v[0] = byte2int(content, times);             v[1] = byte2int(content, next);             o = en(v, k,rounds);             int2byte(o[0], result, times);             int2byte(o[1], result, next);         }         return flag(result);         //return byte2String(flag(result));              }     /**      * 封装后揭秘函数      * @param content byte[] 待解密byte密文数组 若输入不为密文 则返回原文      * @param key byte[] 解密密钥和加密函数相同      * @return byte[] 解密后密文      */     public static byte[] decrypt(byte[] scontent, byte[] key,int rounds) {      if(flag_compare(scontent)==1){       byte[] content=unflag(scontent);         if(content==null||key==null||content.length==0||key.length==0){             return content;         }         if (content.length % 8 != 0) {             throw new IllegalArgumentException("Content cannot be decypted!");         }         byte[] result = null;         int[] k = validateKey3(key); // 密钥设置 函数 见之后说明         int[] v = new int[2];         int[] o = null;         result = new byte[content.length];         int convertTimes = content.length;         int next = 0;         int times = 0;         for (; times < convertTimes; times += 8) { // 分块加密             next = times + 4;             v[0] = byte2int(content, times);             v[1] = byte2int(content, next);             o = de(v, k,rounds);             int2byte(o[0], result, times);             int2byte(o[1], result, next);         }         // 去掉空白            convertTimes = convertTimes-8;         for(times=convertTimes+1;times<content.length;times++){             if(result[times]==(byte)0)break;         }         byte[] tmp=result;         result = new byte[times];         System.arraycopy(tmp,0,result,0,times); // 复制非空区域         return result;         }      else       return scontent;     }          /**      *将四个8位数字转换为一个32位数据      * @param buf byte[] 存储需要转换的byte数组      * @param offset 开始转换位置      * @return一个32位的数字      */     private static int byte2int(byte[] buf, int offset) {         return             ( buf[offset + 3] & 0x000000ff) |             ((buf[offset + 2] & 0x000000ff) << 8) |             ((buf[offset + 1] & 0x000000ff) << 16) |             ((buf[offset ] & 0x000000ff) << 24);     }     /**      * 一个32位数字转换为4个byte型数据      * @param integer 需要进行转换的32位数据      * @param buf byte[] 需要存储byte数据的数组      * @param offset 存储起始位置ַ      */     private static void int2byte(int integer, byte[] buf, int offset) {         buf[offset ] = (byte)(integer >> 24);         buf[offset + 1] = (byte)(integer >> 16);         buf[offset + 2] = (byte)(integer >> 8);         buf[offset + 3] = (byte) integer;     }         /**密钥设定函数 选取16位byte型作为前8byte加密密钥 从原始字符串中第n位开始取8byte 若不满8byte 补零 之后8byte补位 为127-n-i     *     * @param key 原始输入的密钥字符串     * @return 返回加解密密钥     */             private static int[] validateKey3(byte[] key){      byte[] tempkey=new byte[16];      if(key.length-n+1<8){      System.arraycopy(key, n-1, tempkey, 0, key.length-n+1);           for(int i=8;i<16;i++)       tempkey[i]=(byte)(127-n-i);       int k[]=new int[]{           byte2int(tempkey, 0),                    byte2int(tempkey, 4),                    byte2int(tempkey, 8),                    byte2int(tempkey, 12)                };       return k;      }      else{       System.arraycopy(key, n-1, tempkey, 0, 8);       for(int i=8;i<16;i++)        tempkey[i]=(byte)(127-n-i);       int k1[]=new int[]{           byte2int(tempkey, 0),                    byte2int(tempkey, 4),                    byte2int(tempkey, 8),                    byte2int(tempkey, 12)       };       return k1;      }                    }               /**      * 将byte[]数组转换为hex字符串功能的加密函数      */     public static String hex_en(byte[] content,byte[] key,int rounds){      return hex2byte.bytetohex(encrypt(content,key,rounds));     }          /**      * 将hex加密字符串解密函数      * @throws UnsupportedEncodingException      */          public static String hex_de(String content,byte[] key,int rounds) throws UnsupportedEncodingException{      return new String(decrypt(hex2byte.hextobyte(content),key,rounds),"utf-8");     }     /*public static String Base64_en(byte[] content,byte[] key,int rounds){           return Base64.encode(encrypt(content,key,rounds));          }     /**对经过base64编码的秘闻进行解密额函数      *      * @param content      * @param key      * @param rounds      * @return      */     /*public static byte[] Base64_de(String content,byte[] key,int rounds){      return decrypt(Base64.decode(content),key,rounds);     }*/                    /**      * �ӵ�nλ��ʼȡ�����16byte��Ϊ������Կ �����������㣬������������      * @param key��Կbyte����      * @return 4λint����Կ����      */        /* private static int[] validateKey2(byte[] key){      byte[] tempkey1=new byte[16];           if(key.length-n+1<16)      {       System.arraycopy(key, n-1, tempkey1, 0, key.length-n+1);                          int k[]=new int[]{           byte2int(tempkey1, 0),                    byte2int(tempkey1, 4),                    byte2int(tempkey1, 8),                    byte2int(tempkey1, 12)                };       return k;      }      else      {         int[] k1 = new int[] {                   byte2int(key, n-1),                   byte2int(key, n+3),                   byte2int(key, n+7),                   byte2int(key, n+11)      };       return k1;      }             }*/                /**      * У����Կ,�������16�ֽ���ĩβ����ֽ�0����16�ֽ�,�������16�ֽ�����ĩβ������ֽ�      * @param key byte[]      * @return int[] ����Ϊ4�����ֽ���������      * @throws UnsupportedEncodingException      */    /* private static int[] validateKey(byte[] key) {         byte[] tmpkey = key;         if (key.length < 16) { // ����16�ֽ�����0����,Ҳ����ʹ���������õķ�������             tmpkey = new byte[16];             System.arraycopy(key, 0, tmpkey, 0, key.length);         }         int[] k = new int[] {                   byte2int(tmpkey, 0),                   byte2int(tmpkey, 4),                   byte2int(tmpkey, 8),                   byte2int(tmpkey, 12)         };         return k;     }*/           //测试     public static void main(String[] args) throws UnsupportedEncodingException {         //String initstr = "{\"result\":{\"code\":\"2003\",\"msg\":\"json error\"}}";         String initstr = "{ \"system\": { \"ipp\": \"2.0\", \"ver\": \"1.0\", \"lang\": \"en\", \"key\": \"1k8VKDqpOMndSxtDhrExYtTAsV\" }, \"request\": { \"user\": { \"userName\": \"13700000000\", \"token\": \"sjk12ks1kl\", \"pkgName\": \"com.ipp.xx.xx\", \"devType\": \"0\", \"familyId\": 12 }, \"device\": { \"id } } }";         //String initstr = "thisisjiaoiloveyou";         String key = "chdevicecloud";// System.out.print("bytekey=");// byte[] byetkey = key.getBytes("utf-8");// for(int i=0;i<byetkey.length;i++)// System.out.print(" "+byetkey[i]);// System.out.println();// System.out.print("bytecon=");// byte[] bytecon = initstr.getBytes("utf-8");// for(int i=0;i<bytecon.length;i++)// System.out.print(" "+bytecon[i]);// System.out.println();//////////// byte[] enc = encrypt(bytecon,byetkey,16);// for(int i=0;i<enc.length;i++)// System.out.print(" "+enc[i]);// System.out.println();                  System.out.println("发送报文:"+initstr);        // byte[] nn=encrypt(initstr.getBytes("utf-8"),key.getBytes("utf-8"),32);       // System.out.println(" yyy"+new String(encrypt(initstr.getBytes("utf-8"),key.getBytes("utf-8"),32),"utf-8"));      String ss=hex_en(initstr.getBytes("utf-8"),key.getBytes("utf-8"),16);        System.out.println("发送报文加密:"+ss);        String st="7D7D7D7D7D7D7D7DCF48BCD007B45771DC6C815FCB995328A7E19A1125B0C5B6FDC10EE6C81BDB3971F77C5D21AD140F6A56AF9F0B6CCBC6990FE28C9D7F9ADE";        String sss=hex_de(ss,key.getBytes("utf-8"),16);        System.out.println("发送报文解密:"+sss);        //int[] bytekey=validateKey3(key.getBytes("utf-8"));        //for(int i=0;i<bytekey.length;i++)         //System.out.print(" "+bytekey[i]);            //System.out.println();                                                      }               }  /***********************************************hex2byte.java*******************************/package javaTEA;//import java.io.UnsupportedEncodingException;public class hex2byte { public static String bytetohex(byte[] bt){  int len = bt.length;  char[] out=new char[2*bt.length] ;  for(int i=0,j=0;j<len;i+=2,j++){   char temps1 =(char)('0'+ ((bt[j] & 0xf0)>>4));  //System.out.print(temps1);  char temps2 = (char)('0' + (bt[j] & 0x0f));  if(temps1>'9'||temps1<'0'){   switch (temps1-'9'){   case 1: temps1='A';break;   case 2: temps1='B';break;   case 3: temps1='C';break;   case 4: temps1='D';break;   case 5: temps1='E';break;   case 6: temps1='F';break;   }  }  if(temps2>'9'||temps2<'0'){   switch (temps2-'9'){   case 1: temps2='A';break;   case 2: temps2='B';break;   case 3: temps2='C';break;   case 4: temps2='D';break;   case 5: temps2='E';break;   case 6: temps2='F';break;   }  }  out[i]=temps1;  //System.out.print(out[i]);  out[i+1]=temps2;  //System.out.print(out[i+1]);   }  //System.out.println();  return new String(out);  }   public static byte[] hextobyte(String hex){   byte[] out = new byte[hex.length()/2];   //System.out.println("strlen="+hex.length());   int s = 0,s1=0;  for(int j = 0,i=0;i<hex.length()/2;i++,j+=2){    if('0'>hex.charAt(j)||hex.charAt(j)>'9'){    switch (hex.charAt(j)){    case 'A': s=10;break;    case 'B': s=11;break;    case 'C': s=12;break;    case 'D': s=13;break;    case 'E': s=14;break;    case 'F': s=15;break;       }    }   else s=hex.charAt(j)-'0';        if('0'>hex.charAt(j+1)||hex.charAt(j+1)>'9'){     switch (hex.charAt(j+1)){     case 'A': s1=10;break;     case 'B': s1=11;break;     case 'C': s1=12;break;     case 'D': s1=13;break;     case 'E': s1=14;break;     case 'F': s1=15;break;          }   }   else s1=hex.charAt(j+1)-'0';    out[i]=(byte) ( (s&0x0000000f)<<4|(s1&0x0000000f));  }  return out;  }}  

0 0
原创粉丝点击