中文的异或加密有一个很诡异的现象,就是可能会secretKey的值不一样而导致异或后得到的数据为nil,所以在异或加密之前,我们需要将所要加密的字符串转义。代码如下
/**
异或加密
@param plainText 要加密的字符串
@param secretKey 秘钥
@return 加密后返回的字符传
*/
- (NSString *)stringXOREncryptWithPlainText:(NSString *)plainText secretKey:(NSString *)secretKey {
NSData *codeKeyData = [secretKey dataUsingEncoding:NSUTF8StringEncoding];
Byte codeKeyByteAry[codeKeyData.length];
for (int i = 0 ; i < codeKeyData.length; i++) {
NSData *idata = [codeKeyData subdataWithRange:NSMakeRange(i, 1)];
codeKeyByteAry[i] =((Byte*)[idata bytes])[0];
}
NSMutableData *returnData = [[NSMutableData alloc] init];
NSString *charactersToEscape = @"?!@#$^&%*+,:;='\"`<>()[]{}/\\| ";
NSCharacterSet *allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:charactersToEscape] invertedSet];
// 对需要加密的数据进行转义
plainText = [plainText stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
NSData *strData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
for (int i = 0 ; i < strData.length; i++) {
NSData *idata = [strData subdataWithRange:NSMakeRange(i, 1)];
Byte byte =((Byte*)[idata bytes])[0];
Byte byte2 = codeKeyByteAry[i%codeKeyData.length];
Byte returnbyte = byte^byte2;
Byte returnbyteAry[1];
returnbyteAry[0] = returnbyte;
[returnData appendBytes:returnbyteAry length:1];
}
NSString *returnStr = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
return returnStr;
}
当然,在解密的时候要移除转义
/**
异或解密
*/
- (NSString *)stringXORDeocodeWithPlainText:(NSString *)plaintext secretKey:(NSString *)secretKey {
NSData *codeKeyData = [secretKey dataUsingEncoding:NSUTF8StringEncoding];
Byte codeKeyByteAry[codeKeyData.length];
for (int i = 0 ; i < codeKeyData.length; i++) {
NSData *idata = [codeKeyData subdataWithRange:NSMakeRange(i, 1)];
codeKeyByteAry[i] =((Byte*)[idata bytes])[0];
}
NSData *strData = [plaintext dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *returnData = [[NSMutableData alloc] init];
for (int i = 0 ; i < strData.length; i++) {
NSData *idata = [strData subdataWithRange:NSMakeRange(i, 1)];
Byte byte =((Byte*)[idata bytes])[0];
Byte byte2 = codeKeyByteAry[i%codeKeyData.length];
Byte returnbyte = byte^byte2;
Byte returnbyteAry[1];
returnbyteAry[0] = returnbyte;
[returnData appendBytes:returnbyteAry length:1];
}
NSString *returnStr = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
// 要移除转义
returnStr = [returnStr stringByRemovingPercentEncoding];
return returnStr;
}
运行测试结果如下
NSString *input = @"这里是中文异或";
NSString *codeKey = @"secretkey";
NSString *encodeString = [self stringXOREncryptWithPlainText:input secretKey:codeKey];
NSString *decodeString = [self stringXORDeocodeWithPlainText:encodeString secretKey:codeKey];
NSLog(@"加密前:%@",input);
NSLog(@"加密后:%@",encodeString);
NSLog(@"解密后:%@",decodeString);
OK!