DES是一種分組數(shù)據(jù)加密技術(shù)(先將數(shù)據(jù)分成固定長度的小數(shù)據(jù)塊,,之后進(jìn)行加密),,速度較快,,適用于大量數(shù)據(jù)加密
3DES是一種基于DES的加密算法,,使用3個不同密匙對同一個分組數(shù)據(jù)塊進(jìn)行3次加密,如此以使得密文強(qiáng)度更高,。
相較于DES和3DES算法而言,,AES算法有著更高的速度和資源使用效率,安全級別也較之更高了,,被稱為下一代加密標(biāo)準(zhǔn),。
用DES實(shí)現(xiàn)加密和解密的過程:(注釋是我自己理解添加。不對的地方望指出)
.h文件中:
- + (NSString *)encryptWithText:(NSString *)sText;//加密
- + (NSString *)decryptWithText:(NSString *)sText;//解密
.m文件中 (導(dǎo)包:#import"GTMBase64.h"(下面說) #import<CommonCrypto/CommonCryptor.h>)
- + (NSString *)encryptWithText:(NSString *)sText
- {
- //kCCEncrypt 加密
- return [self encrypt:sText encryptOrDecrypt:kCCEncrypt key:@"des"];
- }
-
- + (NSString *)decryptWithText:(NSString *)sText
- {
- //kCCDecrypt 解密
- return [self encrypt:sText encryptOrDecrypt:kCCDecrypt key:@"des"];
- }
-
- + (NSString *)encrypt:(NSString *)sText encryptOrDecrypt:(CCOperation)encryptOperation key:(NSString *)key
- {
- const void *dataIn;
- size_t dataInLength;
-
- if (encryptOperation == kCCDecrypt)//傳遞過來的是decrypt 解碼
- {
- //解碼 base64
- NSData *decryptData = [GTMBase64 decodeData:[sText dataUsingEncoding:NSUTF8StringEncoding]];//轉(zhuǎn)成utf-8并decode
- dataInLength = [decryptData length];
- dataIn = [decryptData bytes];
- }
- else //encrypt
- {
- NSData* encryptData = [sText dataUsingEncoding:NSUTF8StringEncoding];
- dataInLength = [encryptData length];
- dataIn = (const void *)[encryptData bytes];
- }
-
- /*
- DES加密 :用CCCrypt函數(shù)加密一下,,然后用base64編碼下,,傳過去
- DES解密 :把收到的數(shù)據(jù)根據(jù)base64,decode一下,,然后再用CCCrypt函數(shù)解密,,得到原本的數(shù)據(jù)
- */
- CCCryptorStatus ccStatus;
- uint8_t *dataOut = NULL; //可以理解位type/typedef 的縮寫(有效的維護(hù)了代碼,比如:一個人用int,,一個人用long,。最好用typedef來定義)
- size_t dataOutAvailable = 0; //size_t 是操作符sizeof返回的結(jié)果類型
- size_t dataOutMoved = 0;
-
- dataOutAvailable = (dataInLength + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);
- dataOut = malloc( dataOutAvailable * sizeof(uint8_t));
- memset((void *)dataOut, 0x0, dataOutAvailable);//將已開辟內(nèi)存空間buffer的首 1 個字節(jié)的值設(shè)為值 0
-
- NSString *initIv = @"12345678";
- const void *vkey = (const void *) [key UTF8String];
- const void *iv = (const void *) [initIv UTF8String];
-
- //CCCrypt函數(shù) 加密/解密
- ccStatus = CCCrypt(encryptOperation,// 加密/解密
- kCCAlgorithmDES,// 加密根據(jù)哪個標(biāo)準(zhǔn)(des,3des,,aes,。。,。,。)
- kCCOptionPKCS7Padding,// 選項(xiàng)分組密碼算法(des:對每塊分組加一次密 3DES:對每塊分組加三個不同的密)
- vkey, //密鑰 加密和解密的密鑰必須一致
- kCCKeySizeDES,// DES 密鑰的大小(kCCKeySizeDES=8)
- iv, // 可選的初始矢量
- dataIn, // 數(shù)據(jù)的存儲單元
- dataInLength,// 數(shù)據(jù)的大小
- (void *)dataOut,// 用于返回?cái)?shù)據(jù)
- dataOutAvailable,
- &dataOutMoved);
-
- NSString *result = nil;
-
- if (encryptOperation == kCCDecrypt)//encryptOperation==1 解碼
- {
- //得到解密出來的data數(shù)據(jù),,改變?yōu)閡tf-8的字符串
- result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved] encoding:NSUTF8StringEncoding] autorelease];
- }
- else //encryptOperation==0 (加密過程中,,把加好密的數(shù)據(jù)轉(zhuǎn)成base64的)
- {
- //編碼 base64
- NSData *data = [NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved];
- result = [GTMBase64 stringByEncodingData:data];
- }
-
- return result;
- }
這里用到了Base64.。,。從網(wǎng)上找到了一些好的類,,直接貼到這里用
Base64.h
Base64.m
- //
- // GTMBase64.m
- //
- // Copyright 2006-2008 Google Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License"); you may not
- // use this file except in compliance with the License. You may obtain a copy
- // of the License at
- //
- // http://www./licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- // License for the specific language governing permissions and limitations under
- // the License.
- //
-
- #import "GTMBase64.h"
- #import "GTMDefines.h"
-
- static const char *kBase64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- static const char *kWebSafeBase64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
- static const char kBase64PaddingChar = '=';
- static const char kBase64InvalidChar = 99;
-
- static const char kBase64DecodeChars[] = {
- // This array was generated by the following code:
- // #include <sys/time.h>
- // #include <stdlib.h>
- // #include <string.h>
- // main()
- // {
- // static const char Base64[] =
- // "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- // char *pos;
- // int idx, i, j;
- // printf(" ");
- // for (i = 0; i < 255; i += 8) {
- // for (j = i; j < i + 8; j++) {
- // pos = strchr(Base64, j);
- // if ((pos == NULL) || (j == 0))
- // idx = 99;
- // else
- // idx = pos - Base64;
- // if (idx == 99)
- // printf(" %2d, ", idx);
- // else
- // printf(" %2d/*%c*/,", idx, j);
- // }
- // printf("\n ");
- // }
- // }
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 62/*+*/, 99, 99, 99, 63/*/ */,
- 52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/,
- 60/*8*/, 61/*9*/, 99, 99, 99, 99, 99, 99,
- 99, 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/,
- 7/*H*/, 8/*I*/, 9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/,
- 15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/,
- 23/*X*/, 24/*Y*/, 25/*Z*/, 99, 99, 99, 99, 99,
- 99, 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/,
- 33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/,
- 41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/,
- 49/*x*/, 50/*y*/, 51/*z*/, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
- };
-
- static const char kWebSafeBase64DecodeChars[] = {
- // This array was generated by the following code:
- // #include <sys/time.h>
- // #include <stdlib.h>
- // #include <string.h>
- // main()
- // {
- // static const char Base64[] =
- // "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
- // char *pos;
- // int idx, i, j;
- // printf(" ");
- // for (i = 0; i < 255; i += 8) {
- // for (j = i; j < i + 8; j++) {
- // pos = strchr(Base64, j);
- // if ((pos == NULL) || (j == 0))
- // idx = 99;
- // else
- // idx = pos - Base64;
- // if (idx == 99)
- // printf(" %2d, ", idx);
- // else
- // printf(" %2d/*%c*/,", idx, j);
- // }
- // printf("\n ");
- // }
- // }
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 62/*-*/, 99, 99,
- 52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/,
- 60/*8*/, 61/*9*/, 99, 99, 99, 99, 99, 99,
- 99, 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/,
- 7/*H*/, 8/*I*/, 9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/,
- 15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/,
- 23/*X*/, 24/*Y*/, 25/*Z*/, 99, 99, 99, 99, 63/*_*/,
- 99, 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/,
- 33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/,
- 41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/,
- 49/*x*/, 50/*y*/, 51/*z*/, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
- };
-
-
- // Tests a charact to see if it's a whitespace character.
- //
- // Returns:
- // YES if the character is a whitespace character.
- // NO if the character is not a whitespace character.
- //
- FOUNDATION_STATIC_INLINE BOOL IsSpace(unsigned char c) {
- // we use our own mapping here because we don't want anything w/ locale
- // support.
- static BOOL kSpaces[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0-9
- 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 10-19
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20-29
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 30-39
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-49
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50-59
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60-69
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 70-79
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-89
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90-99
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 100-109
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 110-119
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 120-129
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 130-139
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 140-149
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 150-159
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160-169
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 170-179
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 180-189
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 190-199
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 200-209
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 210-219
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 220-229
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 230-239
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 240-249
- 0, 0, 0, 0, 0, 1, // 250-255
- };
- return kSpaces[c];
- }
-
- // Calculate how long the data will be once it's base64 encoded.
- //
- // Returns:
- // The guessed encoded length for a source length
- //
- FOUNDATION_STATIC_INLINE NSUInteger CalcEncodedLength(NSUInteger srcLen,
- BOOL padded) {
- NSUInteger intermediate_result = 8 * srcLen + 5;
- NSUInteger len = intermediate_result / 6;
- if (padded) {
- len = ((len + 3) / 4) * 4;
- }
- return len;
- }
-
- // Tries to calculate how long the data will be once it's base64 decoded.
- // Unlinke the above, this is always an upperbound, since the source data
- // could have spaces and might end with the padding characters on them.
- //
- // Returns:
- // The guessed decoded length for a source length
- //
- FOUNDATION_STATIC_INLINE NSUInteger GuessDecodedLength(NSUInteger srcLen) {
- return (srcLen + 3) / 4 * 3;
- }
-
-
- @interface GTMBase64 (PrivateMethods)
-
- +(NSData *)baseEncode:(const void *)bytes
- length:(NSUInteger)length
- charset:(const char *)charset
- padded:(BOOL)padded;
-
- +(NSData *)baseDecode:(const void *)bytes
- length:(NSUInteger)length
- charset:(const char*)charset
- requirePadding:(BOOL)requirePadding;
-
- +(NSUInteger)baseEncode:(const char *)srcBytes
- srcLen:(NSUInteger)srcLen
- destBytes:(char *)destBytes
- destLen:(NSUInteger)destLen
- charset:(const char *)charset
- padded:(BOOL)padded;
-
- +(NSUInteger)baseDecode:(const char *)srcBytes
- srcLen:(NSUInteger)srcLen
- destBytes:(char *)destBytes
- destLen:(NSUInteger)destLen
- charset:(const char *)charset
- requirePadding:(BOOL)requirePadding;
-
- @end
-
-
- @implementation GTMBase64
-
- //
- // Standard Base64 (RFC) handling
- //
-
- +(NSData *)encodeData:(NSData *)data {
- return [self baseEncode:[data bytes]
- length:[data length]
- charset:kBase64EncodeChars
- padded:YES];
- }
-
- +(NSData *)decodeData:(NSData *)data {
- return [self baseDecode:[data bytes]
- length:[data length]
- charset:kBase64DecodeChars
- requirePadding:YES];
- }
-
- +(NSData *)encodeBytes:(const void *)bytes length:(NSUInteger)length {
- return [self baseEncode:bytes
- length:length
- charset:kBase64EncodeChars
- padded:YES];
- }
-
- +(NSData *)decodeBytes:(const void *)bytes length:(NSUInteger)length {
- return [self baseDecode:bytes
- length:length
- charset:kBase64DecodeChars
- requirePadding:YES];
- }
-
- +(NSString *)stringByEncodingData:(NSData *)data {
- NSString *result = nil;
- NSData *converted = [self baseEncode:[data bytes]
- length:[data length]
- charset:kBase64EncodeChars
- padded:YES];
- if (converted) {
- result = [[[NSString alloc] initWithData:converted
- encoding:NSASCIIStringEncoding] autorelease];
- }
- return result;
- }
-
- +(NSString *)stringByEncodingBytes:(const void *)bytes length:(NSUInteger)length {
- NSString *result = nil;
- NSData *converted = [self baseEncode:bytes
- length:length
- charset:kBase64EncodeChars
- padded:YES];
- if (converted) {
- result = [[[NSString alloc] initWithData:converted
- encoding:NSASCIIStringEncoding] autorelease];
- }
- return result;
- }
-
- +(NSData *)decodeString:(NSString *)string {
- NSData *result = nil;
- NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding];
- if (data) {
- result = [self baseDecode:[data bytes]
- length:[data length]
- charset:kBase64DecodeChars
- requirePadding:YES];
- }
- return result;
- }
-
- //
- // Modified Base64 encoding so the results can go onto urls.
- //
- // The changes are in the characters generated and also the result isn't
- // padded to a multiple of 4.
- // Must use the matching call to encode/decode, won't interop with the
- // RFC versions.
- //
-
- +(NSData *)webSafeEncodeData:(NSData *)data
- padded:(BOOL)padded {
- return [self baseEncode:[data bytes]
- length:[data length]
- charset:kWebSafeBase64EncodeChars
- padded:padded];
- }
-
- +(NSData *)webSafeDecodeData:(NSData *)data {
- return [self baseDecode:[data bytes]
- length:[data length]
- charset:kWebSafeBase64DecodeChars
- requirePadding:NO];
- }
-
- +(NSData *)webSafeEncodeBytes:(const void *)bytes
- length:(NSUInteger)length
- padded:(BOOL)padded {
- return [self baseEncode:bytes
- length:length
- charset:kWebSafeBase64EncodeChars
- padded:padded];
- }
-
- +(NSData *)webSafeDecodeBytes:(const void *)bytes length:(NSUInteger)length {
- return [self baseDecode:bytes
- length:length
- charset:kWebSafeBase64DecodeChars
- requirePadding:NO];
- }
-
- +(NSString *)stringByWebSafeEncodingData:(NSData *)data
- padded:(BOOL)padded {
- NSString *result = nil;
- NSData *converted = [self baseEncode:[data bytes]
- length:[data length]
- charset:kWebSafeBase64EncodeChars
- padded:padded];
- if (converted) {
- result = [[[NSString alloc] initWithData:converted
- encoding:NSASCIIStringEncoding] autorelease];
- }
- return result;
- }
-
- +(NSString *)stringByWebSafeEncodingBytes:(const void *)bytes
- length:(NSUInteger)length
- padded:(BOOL)padded {
- NSString *result = nil;
- NSData *converted = [self baseEncode:bytes
- length:length
- charset:kWebSafeBase64EncodeChars
- padded:padded];
- if (converted) {
- result = [[[NSString alloc] initWithData:converted
- encoding:NSASCIIStringEncoding] autorelease];
- }
- return result;
- }
-
- +(NSData *)webSafeDecodeString:(NSString *)string {
- NSData *result = nil;
- NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding];
- if (data) {
- result = [self baseDecode:[data bytes]
- length:[data length]
- charset:kWebSafeBase64DecodeChars
- requirePadding:NO];
- }
- return result;
- }
-
- @end
-
- @implementation GTMBase64 (PrivateMethods)
-
- //
- // baseEncode:length:charset:padded:
- //
- // Does the common lifting of creating the dest NSData. it creates & sizes the
- // data for the results. |charset| is the characters to use for the encoding
- // of the data. |padding| controls if the encoded data should be padded to a
- // multiple of 4.
- //
- // Returns:
- // an autorelease NSData with the encoded data, nil if any error.
- //
- +(NSData *)baseEncode:(const void *)bytes
- length:(NSUInteger)length
- charset:(const char *)charset
- padded:(BOOL)padded {
- // how big could it be?
- NSUInteger maxLength = CalcEncodedLength(length, padded);
- // make space
- NSMutableData *result = [NSMutableData data];
- [result setLength:maxLength];
- // do it
- NSUInteger finalLength = [self baseEncode:bytes
- srcLen:length
- destBytes:[result mutableBytes]
- destLen:[result length]
- charset:charset
- padded:padded];
- if (finalLength) {
- _GTMDevAssert(finalLength == maxLength, @"how did we calc the length wrong?");
- } else {
- // shouldn't happen, this means we ran out of space
- result = nil;
- }
- return result;
- }
-
- //
- // baseDecode:length:charset:requirePadding:
- //
- // Does the common lifting of creating the dest NSData. it creates & sizes the
- // data for the results. |charset| is the characters to use for the decoding
- // of the data.
- //
- // Returns:
- // an autorelease NSData with the decoded data, nil if any error.
- //
- //
- +(NSData *)baseDecode:(const void *)bytes
- length:(NSUInteger)length
- charset:(const char *)charset
- requirePadding:(BOOL)requirePadding {
- // could try to calculate what it will end up as
- NSUInteger maxLength = GuessDecodedLength(length);
- // make space
- NSMutableData *result = [NSMutableData data];
- [result setLength:maxLength];
- // do it
- NSUInteger finalLength = [self baseDecode:bytes
- srcLen:length
- destBytes:[result mutableBytes]
- destLen:[result length]
- charset:charset
- requirePadding:requirePadding];
- if (finalLength) {
- if (finalLength != maxLength) {
- // resize down to how big it was
- [result setLength:finalLength];
- }
- } else {
- // either an error in the args, or we ran out of space
- result = nil;
- }
- return result;
- }
-
- //
- // baseEncode:srcLen:destBytes:destLen:charset:padded:
- //
- // Encodes the buffer into the larger. returns the length of the encoded
- // data, or zero for an error.
- // |charset| is the characters to use for the encoding
- // |padded| tells if the result should be padded to a multiple of 4.
- //
- // Returns:
- // the length of the encoded data. zero if any error.
- //
- +(NSUInteger)baseEncode:(const char *)srcBytes
- srcLen:(NSUInteger)srcLen
- destBytes:(char *)destBytes
- destLen:(NSUInteger)destLen
- charset:(const char *)charset
- padded:(BOOL)padded {
- if (!srcLen || !destLen || !srcBytes || !destBytes) {
- return 0;
- }
-
- char *curDest = destBytes;
- const unsigned char *curSrc = (const unsigned char *)(srcBytes);
-
- // Three bytes of data encodes to four characters of cyphertext.
- // So we can pump through three-byte chunks atomically.
- while (srcLen > 2) {
- // space?
- _GTMDevAssert(destLen >= 4, @"our calc for encoded length was wrong");
- curDest[0] = charset[curSrc[0] >> 2];
- curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)];
- curDest[2] = charset[((curSrc[1] & 0x0f) << 2) + (curSrc[2] >> 6)];
- curDest[3] = charset[curSrc[2] & 0x3f];
-
- curDest += 4;
- curSrc += 3;
- srcLen -= 3;
- destLen -= 4;
- }
-
- // now deal with the tail (<=2 bytes)
- switch (srcLen) {
- case 0:
- // Nothing left; nothing more to do.
- break;
- case 1:
- // One byte left: this encodes to two characters, and (optionally)
- // two pad characters to round out the four-character cypherblock.
- _GTMDevAssert(destLen >= 2, @"our calc for encoded length was wrong");
- curDest[0] = charset[curSrc[0] >> 2];
- curDest[1] = charset[(curSrc[0] & 0x03) << 4];
- curDest += 2;
- destLen -= 2;
- if (padded) {
- _GTMDevAssert(destLen >= 2, @"our calc for encoded length was wrong");
- curDest[0] = kBase64PaddingChar;
- curDest[1] = kBase64PaddingChar;
- curDest += 2;
- destLen -= 2;
- }
- break;
- case 2:
- // Two bytes left: this encodes to three characters, and (optionally)
- // one pad character to round out the four-character cypherblock.
- _GTMDevAssert(destLen >= 3, @"our calc for encoded length was wrong");
- curDest[0] = charset[curSrc[0] >> 2];
- curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)];
- curDest[2] = charset[(curSrc[1] & 0x0f) << 2];
- curDest += 3;
- destLen -= 3;
- if (padded) {
- _GTMDevAssert(destLen >= 1, @"our calc for encoded length was wrong");
- curDest[0] = kBase64PaddingChar;
- curDest += 1;
- destLen -= 1;
- }
- break;
- }
- // return the length
- return (curDest - destBytes);
- }
-
- //
- // baseDecode:srcLen:destBytes:destLen:charset:requirePadding:
- //
- // Decodes the buffer into the larger. returns the length of the decoded
- // data, or zero for an error.
- // |charset| is the character decoding buffer to use
- //
- // Returns:
- // the length of the encoded data. zero if any error.
- //
- +(NSUInteger)baseDecode:(const char *)srcBytes
- srcLen:(NSUInteger)srcLen
- destBytes:(char *)destBytes
- destLen:(NSUInteger)destLen
- charset:(const char *)charset
- requirePadding:(BOOL)requirePadding {
- if (!srcLen || !destLen || !srcBytes || !destBytes) {
- return 0;
- }
-
- int decode;
- NSUInteger destIndex = 0;
- int state = 0;
- char ch = 0;
- while (srcLen-- && (ch = *srcBytes++) != 0) {
- if (IsSpace(ch)) // Skip whitespace
- continue;
-
- if (ch == kBase64PaddingChar)
- break;
-
- decode = charset[(unsigned int)ch];
- if (decode == kBase64InvalidChar)
- return 0;
-
- // Four cyphertext characters decode to three bytes.
- // Therefore we can be in one of four states.
- switch (state) {
- case 0:
- // We're at the beginning of a four-character cyphertext block.
- // This sets the high six bits of the first byte of the
- // plaintext block.
- _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong");
- destBytes[destIndex] = decode << 2;
- state = 1;
- break;
- case 1:
- // We're one character into a four-character cyphertext block.
- // This sets the low two bits of the first plaintext byte,
- // and the high four bits of the second plaintext byte.
- _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong");
- destBytes[destIndex] |= decode >> 4;
- destBytes[destIndex+1] = (decode & 0x0f) << 4;
- destIndex++;
- state = 2;
- break;
- case 2:
- // We're two characters into a four-character cyphertext block.
- // This sets the low four bits of the second plaintext
- // byte, and the high two bits of the third plaintext byte.
- // However, if this is the end of data, and those two
- // bits are zero, it could be that those two bits are
- // leftovers from the encoding of data that had a length
- // of two mod three.
- _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong");
- destBytes[destIndex] |= decode >> 2;
- destBytes[destIndex+1] = (decode & 0x03) << 6;
- destIndex++;
- state = 3;
- break;
- case 3:
- // We're at the last character of a four-character cyphertext block.
- // This sets the low six bits of the third plaintext byte.
- _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong");
- destBytes[destIndex] |= decode;
- destIndex++;
- state = 0;
- break;
- }
- }
-
- // We are done decoding Base-64 chars. Let's see if we ended
- // on a byte boundary, and/or with erroneous trailing characters.
- if (ch == kBase64PaddingChar) { // We got a pad char
- if ((state == 0) || (state == 1)) {
- return 0; // Invalid '=' in first or second position
- }
- if (srcLen == 0) {
- if (state == 2) { // We run out of input but we still need another '='
- return 0;
- }
- // Otherwise, we are in state 3 and only need this '='
- } else {
- if (state == 2) { // need another '='
- while ((ch = *srcBytes++) && (srcLen-- > 0)) {
- if (!IsSpace(ch))
- break;
- }
- if (ch != kBase64PaddingChar) {
- return 0;
- }
- }
- // state = 1 or 2, check if all remain padding is space
- while ((ch = *srcBytes++) && (srcLen-- > 0)) {
- if (!IsSpace(ch)) {
- return 0;
- }
- }
- }
- } else {
- // We ended by seeing the end of the string.
-
- if (requirePadding) {
- // If we require padding, then anything but state 0 is an error.
- if (state != 0) {
- return 0;
- }
- } else {
- // Make sure we have no partial bytes lying around. Note that we do not
- // require trailing '=', so states 2 and 3 are okay too.
- if (state == 1) {
- return 0;
- }
- }
- }
-
- // If then next piece of output was valid and got written to it means we got a
- // very carefully crafted input that appeared valid but contains some trailing
- // bits past the real length, so just toss the thing.
- if ((destIndex < destLen) &&
- (destBytes[destIndex] != 0)) {
- return 0;
- }
-
- return destIndex;
- }
-
- @end
在Base64 代碼中用到了一個.h文件
Defines.h
- //
- // GTMDefines.h
- //
- // Copyright 2008 Google Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License"); you may not
- // use this file except in compliance with the License. You may obtain a copy
- // of the License at
- //
- // http://www./licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- // License for the specific language governing permissions and limitations under
- // the License.
- //
-
- // ============================================================================
-
- #include <AvailabilityMacros.h>
-
- // Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs
- #ifndef MAC_OS_X_VERSION_10_5
- #define MAC_OS_X_VERSION_10_5 1050
- #endif
- #ifndef MAC_OS_X_VERSION_10_6
- #define MAC_OS_X_VERSION_10_6 1060
- #endif
-
- // ----------------------------------------------------------------------------
- // CPP symbols that can be overridden in a prefix to control how the toolbox
- // is compiled.
- // ----------------------------------------------------------------------------
-
-
- // GTMHTTPFetcher will support logging by default but only hook its input
- // stream support for logging when requested. You can control the inclusion of
- // the code by providing your own definitions for these w/in a prefix header.
- //
- #ifndef GTM_HTTPFETCHER_ENABLE_LOGGING
- #define GTM_HTTPFETCHER_ENABLE_LOGGING 1
- #endif // GTM_HTTPFETCHER_ENABLE_LOGGING
- #ifndef GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING
- #define GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING 0
- #endif // GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING
-
- // By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and
- // GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens
- // when a validation fails. If you implement your own validators, you may want
- // to control their internals using the same macros for consistency.
- #ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT
- #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0
- #endif
-
- // Give ourselves a consistent way to do inlines. Apple's macros even use
- // a few different actual definitions, so we're based off of the foundation
- // one.
- #if !defined(GTM_INLINE)
- #if defined (__GNUC__) && (__GNUC__ == 4)
- #define GTM_INLINE static __inline__ __attribute__((always_inline))
- #else
- #define GTM_INLINE static __inline__
- #endif
- #endif
-
- // Give ourselves a consistent way of doing externs that links up nicely
- // when mixing objc and objc++
- #if !defined (GTM_EXTERN)
- #if defined __cplusplus
- #define GTM_EXTERN extern "C"
- #else
- #define GTM_EXTERN extern
- #endif
- #endif
-
- // Give ourselves a consistent way of exporting things if we have visibility
- // set to hidden.
- #if !defined (GTM_EXPORT)
- #define GTM_EXPORT __attribute__((visibility("default")))
- #endif
-
- // _GTMDevLog & _GTMDevAssert
- //
- // _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for
- // developer level errors. This implementation simply macros to NSLog/NSAssert.
- // It is not intended to be a general logging/reporting system.
- //
- // Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert
- // for a little more background on the usage of these macros.
- //
- // _GTMDevLog log some error/problem in debug builds
- // _GTMDevAssert assert if conditon isn't met w/in a method/function
- // in all builds.
- //
- // To replace this system, just provide different macro definitions in your
- // prefix header. Remember, any implementation you provide *must* be thread
- // safe since this could be called by anything in what ever situtation it has
- // been placed in.
- //
-
- // We only define the simple macros if nothing else has defined this.
- #ifndef _GTMDevLog
-
- #ifdef DEBUG
- #define _GTMDevLog(...) NSLog(__VA_ARGS__)
- #else
- #define _GTMDevLog(...) do { } while (0)
- #endif
-
- #endif // _GTMDevLog
-
- // Declared here so that it can easily be used for logging tracking if
- // necessary. See GTMUnitTestDevLog.h for details.
- @class NSString;
- GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...);
-
- #ifndef _GTMDevAssert
- // we directly invoke the NSAssert handler so we can pass on the varargs
- // (NSAssert doesn't have a macro we can use that takes varargs)
- #if !defined(NS_BLOCK_ASSERTIONS)
- #define _GTMDevAssert(condition, ...) \
- do { \
- if (!(condition)) { \
- [[NSAssertionHandler currentHandler] \
- handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
- file:[NSString stringWithUTF8String:__FILE__] \
- lineNumber:__LINE__ \
- description:__VA_ARGS__]; \
- } \
- } while(0)
- #else // !defined(NS_BLOCK_ASSERTIONS)
- #define _GTMDevAssert(condition, ...) do { } while (0)
- #endif // !defined(NS_BLOCK_ASSERTIONS)
-
- #endif // _GTMDevAssert
-
- // _GTMCompileAssert
- // _GTMCompileAssert is an assert that is meant to fire at compile time if you
- // want to check things at compile instead of runtime. For example if you
- // want to check that a wchar is 4 bytes instead of 2 you would use
- // _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)
- // Note that the second "arg" is not in quotes, and must be a valid processor
- // symbol in it's own right (no spaces, punctuation etc).
-
- // Wrapping this in an #ifndef allows external groups to define their own
- // compile time assert scheme.
- #ifndef _GTMCompileAssert
- // We got this technique from here:
- // http://unixjunkie./2007/10/better-compile-time-asserts_29.html
-
- #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg
- #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)
- #define _GTMCompileAssert(test, msg) \
- typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
- #endif // _GTMCompileAssert
-
- // Macro to allow fast enumeration when building for 10.5 or later, and
- // reliance on NSEnumerator for 10.4. Remember, NSDictionary w/ FastEnumeration
- // does keys, so pick the right thing, nothing is done on the FastEnumeration
- // side to be sure you're getting what you wanted.
- #ifndef GTM_FOREACH_OBJECT
- #if defined(TARGET_OS_IPHONE) || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
- #define GTM_FOREACH_OBJECT(element, collection) \
- for (element in collection)
- #define GTM_FOREACH_KEY(element, collection) \
- for (element in collection)
- #else
- #define GTM_FOREACH_OBJECT(element, collection) \
- for (NSEnumerator * _ ## element ## _enum = [collection objectEnumerator]; \
- (element = [_ ## element ## _enum nextObject]) != nil; )
- #define GTM_FOREACH_KEY(element, collection) \
- for (NSEnumerator * _ ## element ## _enum = [collection keyEnumerator]; \
- (element = [_ ## element ## _enum nextObject]) != nil; )
- #endif
- #endif
-
- // ============================================================================
-
- // ----------------------------------------------------------------------------
- // CPP symbols defined based on the project settings so the GTM code has
- // simple things to test against w/o scattering the knowledge of project
- // setting through all the code.
- // ----------------------------------------------------------------------------
-
- // Provide a single constant CPP symbol that all of GTM uses for ifdefing
- // iPhone code.
- #include <TargetConditionals.h>
- #if TARGET_OS_IPHONE // iPhone SDK
- // For iPhone specific stuff
- #define GTM_IPHONE_SDK 1
- #if TARGET_IPHONE_SIMULATOR
- #define GTM_IPHONE_SIMULATOR 1
- #else
- #define GTM_IPHONE_DEVICE 1
- #endif // TARGET_IPHONE_SIMULATOR
- #else
- // For MacOS specific stuff
- #define GTM_MACOS_SDK 1
- #endif
-
- // Provide a symbol to include/exclude extra code for GC support. (This mainly
- // just controls the inclusion of finalize methods).
- #ifndef GTM_SUPPORT_GC
- #if GTM_IPHONE_SDK
- // iPhone never needs GC
- #define GTM_SUPPORT_GC 0
- #else
- // We can't find a symbol to tell if GC is supported/required, so best we
- // do on Mac targets is include it if we're on 10.5 or later.
- #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
- #define GTM_SUPPORT_GC 0
- #else
- #define GTM_SUPPORT_GC 1
- #endif
- #endif
- #endif
-
- // To simplify support for 64bit (and Leopard in general), we provide the type
- // defines for non Leopard SDKs
- #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
- // NSInteger/NSUInteger and Max/Mins
- #ifndef NSINTEGER_DEFINED
- #if __LP64__ || NS_BUILD_32_LIKE_64
- typedef long NSInteger;
- typedef unsigned long NSUInteger;
- #else
- typedef int NSInteger;
- typedef unsigned int NSUInteger;
- #endif
- #define NSIntegerMax LONG_MAX
- #define NSIntegerMin LONG_MIN
- #define NSUIntegerMax ULONG_MAX
- #define NSINTEGER_DEFINED 1
- #endif // NSINTEGER_DEFINED
- // CGFloat
- #ifndef CGFLOAT_DEFINED
- #if defined(__LP64__) && __LP64__
- // This really is an untested path (64bit on Tiger?)
- typedef double CGFloat;
- #define CGFLOAT_MIN DBL_MIN
- #define CGFLOAT_MAX DBL_MAX
- #define CGFLOAT_IS_DOUBLE 1
- #else /* !defined(__LP64__) || !__LP64__ */
- typedef float CGFloat;
- #define CGFLOAT_MIN FLT_MIN
- #define CGFLOAT_MAX FLT_MAX
- #define CGFLOAT_IS_DOUBLE 0
- #endif /* !defined(__LP64__) || !__LP64__ */
- #define CGFLOAT_DEFINED 1
- #endif // CGFLOAT_DEFINED
- #endif // MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
調(diào)用方法測試:
- NSString *encrypt = [ViewController encryptWithText:@"中華人民共和國萬歲!,!"];
- NSLog(@"enctry = %@",encrypt);
- NSString *decrypt = [ViewController decryptWithText:encrypt];
- NSLog(@"decrypt = %@",decrypt);
輸出結(jié)果:
enctry = IKnyVPAK8eprKHHunG7Ze9tTfU8sIoYho8SFeyFEniK/7wy3u7stKA==
decrypt =中華人民共和國萬歲?。?/strong>
|