⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nsdata-qqcrypt.mm

📁 lumaqq
💻 MM
字号:
/* * LumaQQ - Cross platform QQ client, special edition for Mac * * Copyright (C) 2007 luma <stubma@163.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#import "NSData-QQCrypt.h"#import "ByteTool.h"@implementation NSData (QQCrypt)#pragma makr -#pragma mark auxillary variablechar cipher[8];char* prePlain;char* output;char* plain;int pos;int crypt;int preCrypt;int padding;int contextStart;BOOL header = YES;const char* key;#pragma mark -#pragma mark interface- (NSData*)QQEncrypt:(NSData*)keyData {	return [self QQEncrypt:keyData offset:0 length:[self length]];}- (NSData*)QQDecrypt:(NSData*)keyData {	return [self QQDecrypt:keyData offset:0 length:[self length]];}- (NSData*)QQEncrypt:(NSData*)keyData offset:(int)offset length:(int)length {	const char* bytes = (const char*)[self bytes];	plain = (char*)malloc(8 * sizeof(char));	prePlain = (char*)calloc(8, sizeof(char));	pos = 1;           	padding = 0; 	crypt = preCrypt = 0;	key = (const char*)[keyData bytes];	header = YES;	int i;		// -1 means encrypt to end	if(length == -1)		length = [self length] - offset;		int lengthbak = length;		pos = (length + 0x0A) % 8;	if(pos != 0)		pos = 8 - pos;	int count = length + pos + 10;	NSMutableData* encryptData = [NSMutableData dataWithLength:(pos + 10 + [self length])];	output = (char*)[encryptData mutableBytes];	memcpy(output, bytes, offset);	output += offset;		plain[0] = (char)(([self rand] & 0xF8) | pos);		for(i = 1; i <= pos; i++)		plain[i] = (char)([self rand] & 0xFF);	pos++;		padding = 1;	while(padding <= 2) {		if(pos < 8) {			plain[pos++] = (char)([self rand] & 0xFF);			padding++;		}		if(pos == 8)			[self encrypt8Bytes];	}		i = offset;	while(length > 0) {		if(pos < 8) {			plain[pos++] = bytes[i++];			length--;		}		if(pos == 8)			[self encrypt8Bytes];	}		padding = 1;	while(padding <= 7) {		if(pos < 8) {			plain[pos++] = 0x0;			padding++;		}		if(pos == 8)			[self encrypt8Bytes];	}		free(plain);	free(prePlain);		memcpy(output + count, bytes + offset + lengthbak, [self length] - offset - lengthbak);	return encryptData;}- (NSData*)QQDecrypt:(NSData*)keyData offset:(int)offset length:(int)length {	const char* bytes = (const char*)[self bytes];	crypt = preCrypt = 0;	key = (const char*)[keyData bytes];		int i;	int count, countbak;	int mlen = offset + 8;		// -1 means decrypt to end	if(length == -1)		length = [self length] - offset;		if((length % 8 != 0) || (length < 16)) 		return nil;		prePlain = [self decipher:bytes offset:offset];	pos = prePlain[0] & 0x7;		count = length - pos - 10;	countbak = count;	if(count < 0) 		return nil;		char* m = (char*)calloc(mlen, sizeof(char));	char* mbak = m;		NSMutableData* decryptData = [NSMutableData dataWithLength:(count + [self length] - length)];	output = (char*)[decryptData mutableBytes];	memcpy(output, bytes, offset);	output += offset;		preCrypt = 0;	crypt = 8;	contextStart = 8;	pos++;		padding = 1;	while(padding <= 2) {		if(pos < 8) {			pos++;			padding++;		}		if(pos == 8) {			m = (char*)bytes;			if(![self decrypt8Bytes:bytes offset:offset length:length]) {				free(mbak);				return nil;			}		}	}		i = 0;	while(count != 0) {		if(pos < 8) {			output[i] = (char)(m[offset + preCrypt + pos] ^ prePlain[pos]);			i++;			count--;			pos++;		}		if(pos == 8) {			m = (char*)bytes;			preCrypt = crypt - 8;			if(![self decrypt8Bytes:bytes offset:offset length:length]) {				free(mbak);				return nil;			}		}	}		for(padding = 1; padding < 8; padding++) {		if(pos < 8) {			if((m[offset + preCrypt + pos] ^ prePlain[pos]) != 0) {				free(mbak);				return nil;			};			pos++;		}		if(pos == 8) {			m = (char*)bytes;			preCrypt = crypt;			if(![self decrypt8Bytes:bytes offset:offset length:length]) {				free(mbak);				return nil;			}		}	}		free(mbak);	memcpy(output + countbak, bytes + offset + length, [self length] - offset - length);	return decryptData;}#pragma mark -#pragma mark internal use- (int)rand {	return random();}- (char*)encipher:(const char*)bytes {	// iterate times	int loop = 0x10;		// variables	UInt32 y = [ByteTool getUInt32:bytes offset:0 length:4];	UInt32 z = [ByteTool getUInt32:bytes offset:4 length:4];	UInt32 a = [ByteTool getUInt32:key offset:0 length:4];	UInt32 b = [ByteTool getUInt32:key offset:4 length:4];	UInt32 c = [ByteTool getUInt32:key offset:8 length:4];	UInt32 d = [ByteTool getUInt32:key offset:12 length:4];       	// control variable	// TEA delta,(sqr(5) - 1) * 2^31	UInt32 sum = 0;	UInt32 delta = 0x9E3779B9;		// iterate	while (loop-- > 0) {		sum += delta;		y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);		z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);	}		// output crypted data	[ByteTool writeUInt32:cipher value:y at:0];	[ByteTool writeUInt32:cipher value:z at:4];	return cipher;}- (void)encrypt8Bytes {	// 这plain ^ preCrypt	for(pos = 0; pos < 8; pos++) {		if(header) 			plain[pos] ^= prePlain[pos];		else			plain[pos] ^= output[preCrypt + pos];	}	// f(plain ^ preCrypt)	memcpy(output + crypt, [self encipher:plain], 8);		// f(plain ^ preCrypt) ^ prePlain	for(pos = 0; pos < 8; pos++)		output[crypt + pos] ^= prePlain[pos];	memcpy(prePlain, plain, 8);		// finish	preCrypt = crypt;	crypt += 8;      	pos = 0;	header = NO;   }- (char*)decipher:(const char*)bytes {	return [self decipher:bytes offset:0];}- (char*)decipher:(const char*)bytes offset:(int)offset {	// iterate times	int loop = 0x10;		// variables	UInt32 y = [ByteTool getUInt32:bytes offset:offset length:4];	UInt32 z = [ByteTool getUInt32:bytes offset:offset + 4 length:4];	UInt32 a = [ByteTool getUInt32:key offset:0 length:4];	UInt32 b = [ByteTool getUInt32:key offset:4 length:4];	UInt32 c = [ByteTool getUInt32:key offset:8 length:4];	UInt32 d = [ByteTool getUInt32:key offset:12 length:4];	// control variable	UInt32 sum = 0xE3779B90;	UInt32 delta = 0x9E3779B9;		// iterate	while(loop-- > 0) {		z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);		y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);		sum -= delta;	}		// output	[ByteTool writeUInt32:cipher value:y at:0];	[ByteTool writeUInt32:cipher value:z at:4];	return cipher;}- (BOOL)decrypt8Bytes:(const char*)bytes offset:(int)offset length:(int)length {	for(pos = 0; pos < 8; pos++) {		if(contextStart + pos >= length) 			return YES;		prePlain[pos] ^= bytes[offset + crypt + pos];	}		// d(crypt ^ prePlain)	prePlain = [self decipher:prePlain];	if(prePlain == nil)		return NO;		contextStart += 8;	crypt += 8;	pos = 0;	return YES;}@end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -