【数据加密】使用XXTEA对NSData进行加密

最近做的项目中数据传输要加密,开始使用的是AES加密算法,这个是本来就有高手封装好了的,在ios中对NSData进行加密,拿来直接用就ok了。但是考虑到传输数据大,频率高,服务器每秒可能要跟N多的用户交互,于是另寻它径。
后来了解到XXTEA效率挺高的,测试了一下加密解密可以保证在1毫秒之内完成。ok,就是它了。XXTEA加密算法是对TEA加密算法的升级,仍然是用128位(16字节)的密钥对64位(8字节)信息进行加密,也就是说加密的数据必须是8字节的整数倍,不够的话自动补齐。
不过,XXTEA是C语言实现的,当然没法传递NSData进行加密。网上找了N久,但是好像没有人给出现成的封装方法对NSData加密,只能自己封装了。
直接上代码:
XXTEA的C语言实现:(最原始的代码)
#define MX (z>>5^y<<2) + (y>>3^z<<4)^(sum^y) + (k[p&3^e]^z);

  long btea(long* v, long n, long* k) {
    unsigned long z=v[n-1], y=v[0], sum=0, e, DELTA=0x9e3779b9;
    long p, q ;
    if (n > 1) {          /* Coding Part */
      q = 6 + 52/n;
      while (q-- > 0) {
        sum += DELTA;
        e = (sum >> 2) & 3;
        for (p=0; p<n-1; p++) y = v[p+1], z = v[p] += MX;
        y = v[0];
        z = v[n-1] += MX;
      }
      return 0 ;
    } else if (n < -1) {  /* Decoding Part */
      n = -n;
      q = 6 + 52/n;
      sum = q*DELTA ;
      while (sum != 0) {
        e = (sum >> 2) & 3;
        for (p=n-1; p>0; p--) z = v[p-1], y = v[p] -= MX;
        z = v[n-1];
        y = v[0] -= MX;
        sum -= DELTA;
      }
      return 0;
    }
    return 1;
  }
封装后的程序
**********************************XXTEA.h***********************************
/*
* 此类是对XXTEA官方算法进行的封装,XXTEA信息详见http://en.wikipedia.org/wiki/XXTEA
*/

#ifndef XXTEA_h
#define XXTEA_h

#include "stdlib.h"
#include "stdio.h"
#include <string.h>

#ifndef XXTEA_TYPE
#define XXTEA_TYPE int         // 一种32位长的数据类型,因int在32bit和64bit系统中都是32位的,故直接用int
#endif

class XXTEA {
public:
    XXTEA();
    ~XXTEA();
   
public:
    /**
     *     @brief     获得输出缓冲区的长度
     *
     *     @param      nLength      输入缓冲区长度
     *     @param      isEncode      TRUE 即为加密,FALSE即为解密
     *
     *     @return     返回所需长度
     */
    static size_t XXTEAGetBufferLength(size_t nLength, bool isEncode);
   
    /**
     *     @brief     对数据流进行加密
     *
     *     @param      lpDstBuffer      目标缓冲区
     *     @param      lpSrcBuffer      源缓冲区
     *     @param      nLength      源缓冲区长度
     *     @param      lpKey      密钥
     *
     *     @return     加密是否成功
     */
    static bool XXTEAEncode(char* lpDstBuffer, const char* lpSrcBuffer, size_t nLength, const XXTEA_TYPE* lpKey);

    /**
     *     @brief     对数据流进行解密
     *
     *     @param      lpDstBuffer      目标缓冲区
     *     @param      lpSrcBuffer      源缓冲区
     *     @param      nLength      源缓冲区长度
     *     @param      lpKey      密钥
     *
     *     @return     解密是否成功
     */
    static bool XXTEADecode(char* lpDstBuffer, const char* lpSrcBuffer, size_t nLength, const XXTEA_TYPE* lpKey);
   

private:
    /**
     *     @brief     XXTEA官方算法,此类即是对其进行封装,详见http://en.wikipedia.org/wiki/XXTEA
     *
     *     @param      v      加解密数据流
     *     @param      n      加解密长度,n > 1为加密,n < -1为解密
     *     @param      k      密钥      注意:形式参数k需和MX中的k对应
     *
     *     @return     返回0表示加解密成功,返回1表示失败
     */
    static long btea(XXTEA_TYPE* v, long n, const XXTEA_TYPE* k);

    /**
     *     @brief     正常字符串以16进制保存
     *
     *     @param      surBuffer      源缓冲区
     *     @param      length      源缓冲区长度
     *     @param      dstBuffer      目标缓冲区
     */
    static void StringToHex(const char* surBuffer, int length, char* dstBuffer);

    /**
     *     @brief     16进制字符串解析成正常字符串
     *
     *     @param      surBuffer      源缓冲区
     *     @param      dstBuffer      目标缓冲区
     *
     *     @return     目标缓冲区的长度
     */
    static int HexToString(const char* surBuffer,  char* dstBuffer);
};

#endif

**********************************XXTEA.cpp*********************************
#include "XXTEA.h"
#define     MX      (z>>5^y<<2) + (y>>3^z<<4)^(sum^y) + (k[p&3^e]^z);
#define     XXTEA_ALIGNMENT_BYTES                 4

XXTEA::XXTEA(){
   
}

XXTEA::~XXTEA(){
   
}

size_t XXTEA::XXTEAGetBufferLength(size_t nLength, bool isEncode){
    if (isEncode) {
        size_t nSize = nLength / XXTEA_ALIGNMENT_BYTES + (nLength % XXTEA_ALIGNMENT_BYTES  ? 1 : 0);
        return (nSize * XXTEA_ALIGNMENT_BYTES * 2 + 1);
    }
    else {
        return (nLength / 2 + 1);
    }
}

bool XXTEA::XXTEAEncode(char* lpDstBuffer, const char* lpSrcBuffer, size_t nLength, const XXTEA_TYPE* lpKey){
    long ret = 1;
    if (nLength > XXTEA_ALIGNMENT_BYTES && lpDstBuffer && lpSrcBuffer) {
        size_t nSize = nLength / XXTEA_ALIGNMENT_BYTES + (nLength % XXTEA_ALIGNMENT_BYTES  ? 1 : 0);
        char* data = (char*)malloc(nSize * XXTEA_ALIGNMENT_BYTES * 2);
        memset(data, 0, nSize * XXTEA_ALIGNMENT_BYTES * 2);
        memcpy(data, lpSrcBuffer, nLength);
        ret = btea((XXTEA_TYPE*)data, nSize, lpKey);
        memset(lpDstBuffer, 0, XXTEAGetBufferLength(nLength, true));
        StringToHex(data, (int)nSize * XXTEA_ALIGNMENT_BYTES, lpDstBuffer);
        free(data);
    }
    return (ret == 0);
}

bool XXTEA::XXTEADecode(char* lpDstBuffer, const char* lpSrcBuffer, size_t nLength, const XXTEA_TYPE* lpKey){
    long ret = 1;
    if (nLength > XXTEA_ALIGNMENT_BYTES * 2 && lpDstBuffer && lpSrcBuffer) {
        size_t nSize = XXTEAGetBufferLength(nLength, false);
        memset(lpDstBuffer, 0, nSize);
        HexToString(lpSrcBuffer, lpDstBuffer);
        ret = btea((XXTEA_TYPE*)lpDstBuffer, -((nSize - 1)/ XXTEA_ALIGNMENT_BYTES), lpKey);
    }
    return (ret == 0);
}

long XXTEA::btea(XXTEA_TYPE* v, long n, const XXTEA_TYPE* k) {
    unsigned XXTEA_TYPE z, y;
    unsigned long sum = 0, e, DELTA = 0x9e3779b9;
    long p, q;
    if (n > 1) {          /* Coding Part */
        z = v[n-1];
        q = 6 + 52 / n;
        while (q-- > 0) {
            sum += DELTA;
            e = (sum >> 2) & 3;
            for (p = 0; p < n-1; ++p) y = v[p+1], z = v[p] += MX;
            y = v[0];
            z = v[n-1] += MX;
        }
        return 0;
    } else if (n < -1) {  /* Decoding Part */
        y = v[0];
        n = -n;
        q = 6 + 52 / n;
        sum = q * DELTA ;
        while (sum != 0) {
            e = (sum >> 2) & 3;
            for (p = n-1; p > 0; --p) z = v[p-1], y = v[p] -= MX;
            z = v[n-1];
            y = v[0] -= MX;
            sum -= DELTA;
        }
        return 0;
    }
    return 1;
}

void XXTEA::StringToHex(const char* surBuffer, int length, char* dstBuffer){
    for (int i = 0; i < length; i++)
    {
        sprintf(&dstBuffer[2*i], "%02X", (unsigned char)surBuffer[i]);
    }
    dstBuffer[2 * length] = '\0';
}

int XXTEA::HexToString(const char* surBuffer,  char* dstBuffer){
    size_t length = strlen((char*)surBuffer) ;
    for(int i = 0; i < length/2; i++)
    {
        int temp;
        sscanf(&surBuffer[2 * i], "%02X", &temp);
        dstBuffer[i] = (char)temp;
    }
    dstBuffer[length/2] = '\0';
    return (int)strlen((char*)dstBuffer);
}

********************************XXTEAHELP.h********************************
#import <Foundation/Foundation.h>

@interface XXTEAHELP : NSObject{
   
}

+(NSData*) encodeWithData:(NSData *)data;
+(NSData*) decodeWithData:(NSData *)data;

@end

********************************XXTEAHELP.mm*******************************
#import "XXTEAHELP.h"
#include "XXTEA.h"

@implementation XXTEAHELP

+(NSData*) encodeWithData:(NSData *)data
{
    char *ch = (char *)[data bytes];
    size_t length = XXTEA::XXTEAGetBufferLength(strlen(ch) + 1, true);
    char* encodeBuffer = new char[length];
    XXTEA_TYPE key[4] = {0x12345678, 0x734a67fc, 0x3367a642, 0x78432562};
    XXTEA::XXTEAEncode(encodeBuffer, ch, strlen(ch) +1, key);
    void *buffer = (void *)encodeBuffer;
    data = [NSData dataWithBytes:buffer length:3*(strlen(ch)+1)];
   
    return data;
}

+(NSData*) decodeWithData:(NSData *)data
{
    XXTEA_TYPE key[4] = {0x12345678, 0x734a67fc, 0x3367a642, 0x78432562};
    const char *en = (const char *)[data bytes];
    size_t length = XXTEA::XXTEAGetBufferLength((strlen(en) + 1)/2, true);
    char *de = new char[XXTEA::XXTEAGetBufferLength(length, false)];
    XXTEA::XXTEADecode(de, en, length, key);
    void *buf = (void *)de;
    data = [NSData dataWithBytes:buf length:strlen(de)+1];
   
    return data;
}



********************************使用方法*******************************
    NSString *str = @"Hello World!hogablgsjlwobg1025";
    NSMutableData *data = [[NSMutableData alloc] init];
    [data appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
    NSLog(@"加密前:~~~~~~~~~~~~~ %@",data);
    data = (NSMutableData *)[XXTEAHELP encodeWithData:data];
    NSLog(@"加密后:~~~~~~~~~~~~~ %@",data);
    data = (NSMutableData *)[XXTEAHELP decodeWithData:data];
    NSLog(@"解密后:~~~~~~~~~~~~~ %@",data);
    NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值