TEA算法多语言实现——Java

主要分为两部分  加解密部分和编解码部分涉及两个文件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;
  }
}
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值