3des 加密 记录

php服务器,java服务器,androidios开发兼容的3des加密解密,

php 

<?phpclass DES3 {

var $key = "my.oschina.net/penngo?#@";

var $iv = "01234567";

function encrypt($input){

$size = mcrypt_get_block_size(MCRYPT_3DES,MCRYPT_MODE_CBC);

$input = $this->pkcs5_pad($input, $size);

$key = str_pad($this->key,24,'0');

$td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');

if( $this->iv == '' )

{

$iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);

}

else

{

$iv = $this->iv;

}

@mcrypt_generic_init($td, $key, $iv);

$data = mcrypt_generic($td, $input);

mcrypt_generic_deinit($td);

mcrypt_module_close($td);

$data = base64_encode($data);

return $data;

}

function decrypt($encrypted){

$encrypted = base64_decode($encrypted);

$key = str_pad($this->key,24,'0');

$td = mcrypt_module_open(MCRYPT_3DES,'',MCRYPT_MODE_CBC,'');

if( $this->iv == '' )

{

$iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);

}

else

{

$iv = $this->iv;

}

$ks = mcrypt_enc_get_key_size($td);

@mcrypt_generic_init($td, $key, $iv);

$decrypted = mdecrypt_generic($td, $encrypted);

mcrypt_generic_deinit($td);

mcrypt_module_close($td);

$y=$this->pkcs5_unpad($decrypted);

return $y;

}

function pkcs5_pad ($text, $blocksize) {

$pad = $blocksize - (strlen($text) % $blocksize);

return $text . str_repeat(chr($pad), $pad);

}

function pkcs5_unpad($text){

$pad = ord($text{strlen($text)-1});

if ($pad > strlen($text)) {

return false;

}

if (strspn($text, chr($pad), strlen($text) - $pad) != $pad){

return false;

}

return substr($text, 0, -1 * $pad);

}

function PaddingPKCS7($data) {

$block_size = mcrypt_get_block_size(MCRYPT_3DES, MCRYPT_MODE_CBC);

$padding_char = $block_size - (strlen($data) % $block_size);

$data .= str_repeat(chr($padding_char),$padding_char);

return $data;

}

}

$des = new DES3();echo $ret = $des->encrypt("来自http://my.oschina.net/penngo的博客") . "\n";echo $des->decrypt($ret) . "\n";

java(android)

import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import java.security.Key;  

import javax.crypto.Cipher;  import javax.crypto.SecretKeyFactory;  import javax.crypto.spec.DESedeKeySpec;  import javax.crypto.spec.IvParameterSpec;  

        /** 

  * 3DES加密工具类 

  */ public class DES3 {  

     // 密钥  

     private final static String secretKey = "my.oschina.net/penngo?#@" ;   

     // 向量  

     private final static String iv = "01234567" ;  

     // 加解密统一使用的编码方式  

     private final static String encoding = "utf-8" ;  

        

     /** 

      * 3DES加密 

      *  

      * @param plainText 普通文本 

      * @return 

      * @throws Exception  

      */ 

     public static String encode(String plainText) throws Exception {  

         Key deskey = null ;  

         DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());  

         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" );  

         deskey = keyfactory.generateSecret(spec);  

        

         Cipher cipher = Cipher.getInstance( "desede/CBC/PKCS5Padding" );  

         IvParameterSpec ips = new IvParameterSpec(iv.getBytes());  

         cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);  

         byte [] encryptData = cipher.doFinal(plainText.getBytes(encoding));  

         return Base64.encode(encryptData);  

     }  

        

     /** 

      * 3DES解密 

      *  

      * @param encryptText 加密文本 

      * @return 

      * @throws Exception 

      */ 

     public static String decode(String encryptText) throws Exception {  

         Key deskey = null ;  

         DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());   

         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" );  

         deskey = keyfactory.generateSecret(spec);  

         Cipher cipher = Cipher.getInstance( "desede/CBC/PKCS5Padding" );  

         IvParameterSpec ips = new IvParameterSpec(iv.getBytes());  

         cipher.init(Cipher.DECRYPT_MODE, deskey, ips);  

        

         byte [] decryptData = cipher.doFinal(Base64.decode(encryptText));  

        

         return new String(decryptData, encoding);  

     }  

     

  public static String padding(String str) {

byte[] oldByteArray;

try {

oldByteArray = str.getBytes("UTF8");

int numberToPad = 8 - oldByteArray.length % 8;

byte[] newByteArray = new byte[oldByteArray.length + numberToPad];

System.arraycopy(oldByteArray, 0, newByteArray, 0,

oldByteArray.length);

for (int i = oldByteArray.length; i < newByteArray.length; ++i) {

newByteArray[i] = 0;

}

return new String(newByteArray, "UTF8");

} catch (UnsupportedEncodingException e) {

System.out.println("Crypter.padding UnsupportedEncodingException");

}

return null;

}

/** 

  * Base64编码工具类 

  * 

  */ 

public static class Base64 {  

     private static final char [] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" .toCharArray();  

        

     public static String encode( byte [] data) {  

         int start = 0 ;  

         int len = data.length;  

         StringBuffer buf = new StringBuffer(data.length * 3 / 2 );  

        

         int end = len - 3 ;  

         int i = start;  

         int n = 0 ;  

        

         while (i <= end) {  

             int d = (((( int ) data[i]) & 0x0ff ) << 16 ) | (((( int ) data[i + 1 ]) & 0x0ff ) << 8 ) | ((( int ) data[i + 2 ]) & 0x0ff );  

        

             buf.append(legalChars[(d >> 18 ) & 63 ]);  

             buf.append(legalChars[(d >> 12 ) & 63 ]);  

             buf.append(legalChars[(d >> 6 ) & 63 ]);  

             buf.append(legalChars[d & 63 ]);  

        

             i += 3 ;  

        

             if (n++ >= 14 ) {  

                 n = 0 ;  

                 buf.append( " " );  

             }  

         }  

        

         if (i == start + len - 2 ) {  

             int d = (((( int ) data[i]) & 0x0ff ) << 16 ) | (((( int ) data[i + 1 ]) & 255 ) << 8 );  

        

             buf.append(legalChars[(d >> 18 ) & 63 ]);  

             buf.append(legalChars[(d >> 12 ) & 63 ]);  

             buf.append(legalChars[(d >> 6 ) & 63 ]);  

             buf.append( "=" );  

         } else if (i == start + len - 1 ) {  

             int d = ((( int ) data[i]) & 0x0ff ) << 16 ;  

        

             buf.append(legalChars[(d >> 18 ) & 63 ]);  

             buf.append(legalChars[(d >> 12 ) & 63 ]);  

             buf.append( "==" );  

         }  

        

         return buf.toString();  

     }  

        

     private static int decode( char c) {  

         if (c >= 'A' && c <= 'Z' )  

             return (( int ) c) - 65 ;  

         else if (c >= 'a' && c <= 'z' )  

             return (( int ) c) - 97 + 26 ;  

         else if (c >= '0' && c <= '9' )  

             return (( int ) c) - 48 + 26 + 26 ;  

         else 

             switch (c) {  

             case '+' :  

                 return 62 ;  

             case '/' :  

                 return 63 ;  

             case '=' :  

                 return 0 ;  

             default :  

                 throw new RuntimeException( "unexpected code: " + c);  

             }  

     }  

        

     /** 

      * Decodes the given Base64 encoded String to a new byte array. The byte array holding the decoded data is returned. 

      */ 

        

     public static byte [] decode(String s) {  

        

         ByteArrayOutputStream bos = new ByteArrayOutputStream();  

         try {  

             decode(s, bos);  

         } catch (IOException e) {  

             throw new RuntimeException();  

         }  

         byte [] decodedBytes = bos.toByteArray();  

         try {  

             bos.close();  

             bos = null ;  

         } catch (IOException ex) {  

             System.err.println( "Error while decoding BASE64: " + ex.toString());  

         }  

         return decodedBytes;  

     }  

        

     private static void decode(String s, OutputStream os) throws IOException {  

         int i = 0 ;  

        

         int len = s.length();  

        

         while ( true ) {  

             while (i < len && s.charAt(i) <= ' ' )  

                 i++;  

        

             if (i == len)  

                 break ;  

        

             int tri = (decode(s.charAt(i)) << 18 ) + (decode(s.charAt(i + 1 )) << 12 ) + (decode(s.charAt(i + 2 )) << 6 ) + (decode(s.charAt(i + 3 )));  

        

             os.write((tri >> 16 ) & 255 );  

             if (s.charAt(i + 2 ) == '=' )  

                 break ;  

             os.write((tri >> 8 ) & 255 );  

             if (s.charAt(i + 3 ) == '=' )  

                 break ;  

             os.write(tri & 255 );  

        

             i += 4 ;  

         }  

     }  

     

     public static void main(String[] args) throws Exception{

      String plainText = "来自http://my.oschina.net/penngo的博客";

      String encryptText = DES3.encode(plainText);

      System.out.println(encryptText);

      System.out.println(DES3.decode(encryptText));

      

     }

}

Ojbective-C(ios)

//  //  DES3Util.h  //  #import <Foundation/Foundation.h>  @interface DES3Util : NSObject {  

}  // 加密方法  

+ (NSString*)encrypt:(NSString*)plainText;  // 解密方法  

+ (NSString*)decrypt:(NSString*)encryptText;  @end 

//  //  DES3Util.m  //  

        #import "DES3Util.h"  #import <CommonCrypto/CommonCryptor.h>  #import "GTMBase64.h"  #define gkey            @"my.oschina.net/penngo?#@"  #define gIv             @"01234567"  

        @implementation DES3Util  // 加密方法  

+ (NSString*)encrypt:(NSString*)plainText {  

     NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];  

     size_t plainTextBufferSize = [data length];  

     const void *vplainText = (const void *)[data bytes];  

            

     CCCryptorStatus ccStatus;  

     uint8_t *bufferPtr = NULL;  

     size_t bufferPtrSize = 0;  

     size_t movedBytes = 0;  

            

     bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);  

     bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));  

     memset((void *)bufferPtr, 0x0, bufferPtrSize);  

            

     const void *vkey = (const void *) [gkey UTF8String];  

     const void *vinitVec = (const void *) [gIv UTF8String];  

            

     ccStatus = CCCrypt(kCCEncrypt,  

                        kCCAlgorithm3DES,  

                        kCCOptionPKCS7Padding,  

                        vkey,  

                        kCCKeySize3DES,  

                        vinitVec,  

                        vplainText,  

                        plainTextBufferSize,  

                        (void *)bufferPtr,  

                        bufferPtrSize,  

                        &movedBytes);  

            

     NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];  

     NSString *result = [GTMBase64 stringByEncodingData:myData];  

     return result;  

}  

        // 解密方法  

+ (NSString*)decrypt:(NSString*)encryptText {  

     NSData *encryptData = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];  

     size_t plainTextBufferSize = [encryptData length];  

     const void *vplainText = [encryptData bytes];  

            

     CCCryptorStatus ccStatus;  

     uint8_t *bufferPtr = NULL;  

     size_t bufferPtrSize = 0;  

     size_t movedBytes = 0;  

     bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);  

     bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));  

     memset((void *)bufferPtr, 0x0, bufferPtrSize);     

     const void *vkey = (const void *) [gkey UTF8String];  

     const void *vinitVec = (const void *) [gIv UTF8String];  

            

     ccStatus = CCCrypt(kCCDecrypt,  

                        kCCAlgorithm3DES,  

                        kCCOptionPKCS7Padding,  

                        vkey,  

                        kCCKeySize3DES,  

                        vinitVec,  

                        vplainText,  

                        plainTextBufferSize,  

                        (void *)bufferPtr,  

                        bufferPtrSize,  

                        &movedBytes);  

            

     NSString *result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr   

                                 length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding] autorelease];  

     return result;  

}  

        @end

  GTMBase64.h  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.apache.org/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.

// David Lee make changes:// Remove dependency on GTMDefines.h// add some string to string function

#import <Foundation/Foundation.h>

// GTMBase64/ Helper for handling Base64 and WebSafeBase64 encodings/ The webSafe methods use different character set and also the results aren't/// always padded to a multiple of 4 characters.  This is done so the resulting/// data can be used in urls and url query arguments without needing any/// encoding.  You must use the webSafe* methods together, the data does not/// interop with the RFC methods.//@interface GTMBase64 : NSObject

 Standard Base64 (RFC) handling//

// encodeData:/ Base64 encodes contents of the NSData object./ Returns:///   A new autoreleased NSData with the encoded payload.  nil for any error.//

+(NSData *)encodeData:(NSData *)data;

// decodeData:/ Base64 decodes contents of the NSData object./ Returns:///   A new autoreleased NSData with the decoded payload.  nil for any error.//

+(NSData *)decodeData:(NSData *)data;

// encodeBytes:length:/ Base64 encodes the data pointed at by |bytes|./ Returns:///   A new autoreleased NSData with the encoded payload.  nil for any error.//

+(NSData *)encodeBytes:(const void *)bytes length:(NSUInteger)length;

// decodeBytes:length:/ Base64 decodes the data pointed at by |bytes|./ Returns:///   A new autoreleased NSData with the encoded payload.  nil for any error.//

+(NSData *)decodeBytes:(const void *)bytes length:(NSUInteger)length;

// stringByEncodingData:/ Base64 encodes contents of the NSData object./ Returns:///   A new autoreleased NSString with the encoded payload.  nil for any error.//

+(NSString *)stringByEncodingData:(NSData *)data;

// stringByEncodingBytes:length:/ Base64 encodes the data pointed at by |bytes|./ Returns:///   A new autoreleased NSString with the encoded payload.  nil for any error.//

+(NSString *)stringByEncodingBytes:(const void *)bytes length:(NSUInteger)length;

// decodeString:/ Base64 decodes contents of the NSString./ Returns:///   A new autoreleased NSData with the decoded payload.  nil for any error.//

+(NSData *)decodeString:(NSString *)string;

 Modified Base64 encoding so the results can go onto urls. The changes are in the characters generated and also allows the result to// not be padded to a multiple of 4.// Must use the matching call to encode/decode, won't interop with the// RFC versions.//

// webSafeEncodeData:padded:/ WebSafe Base64 encodes contents of the NSData object.  If |padded| is YES/// then padding characters are added so the result length is a multiple of 4./ Returns:///   A new autoreleased NSData with the encoded payload.  nil for any error.//

+(NSData *)webSafeEncodeData:(NSData *)data

                      padded:(BOOL)padded;

// webSafeDecodeData:/ WebSafe Base64 decodes contents of the NSData object./ Returns:///   A new autoreleased NSData with the decoded payload.  nil for any error.//

+(NSData *)webSafeDecodeData:(NSData *)data;

// webSafeEncodeBytes:length:padded:/ WebSafe Base64 encodes the data pointed at by |bytes|.  If |padded| is YES/// then padding characters are added so the result length is a multiple of 4./ Returns:///   A new autoreleased NSData with the encoded payload.  nil for any error.//

+(NSData *)webSafeEncodeBytes:(const void *)bytes

                       length:(NSUInteger)length

                       padded:(BOOL)padded;

// webSafeDecodeBytes:length:/ WebSafe Base64 decodes the data pointed at by |bytes|./ Returns:///   A new autoreleased NSData with the encoded payload.  nil for any error.//

+(NSData *)webSafeDecodeBytes:(const void *)bytes length:(NSUInteger)length;

// stringByWebSafeEncodingData:padded:/ WebSafe Base64 encodes contents of the NSData object.  If |padded| is YES/// then padding characters are added so the result length is a multiple of 4./ Returns:///   A new autoreleased NSString with the encoded payload.  nil for any error.//

+(NSString *)stringByWebSafeEncodingData:(NSData *)data

                                  padded:(BOOL)padded;

// stringByWebSafeEncodingBytes:length:padded:/ WebSafe Base64 encodes the data pointed at by |bytes|.  If |padded| is YES/// then padding characters are added so the result length is a multiple of 4./ Returns:///   A new autoreleased NSString with the encoded payload.  nil for any error.//

+(NSString *)stringByWebSafeEncodingBytes:(const void *)bytes

                                   length:(NSUInteger)length

                                   padded:(BOOL)padded;

// webSafeDecodeString:/ WebSafe Base64 decodes contents of the NSString./ Returns:///   A new autoreleased NSData with the decoded payload.  nil for any error.//

+(NSData *)webSafeDecodeString:(NSString *)string;

// David Lee new added function/// Returns:// A new autoreleased NSString with Base64 encoded NSString

+(NSString *)stringByBase64String:(NSString *)base64String;

// David Lee new added function/// Returns:// A new autoreleased Base64 encoded NSString with  NSString

+(NSString *)base64StringBystring:(NSString *)string;@end

  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.apache.org/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.// David Lee make changes:// Remove dependency on GTMDefines.h// add some string to string function

#import "GTMBase64.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 character 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.//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//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.// Unlike 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//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;

}

// David Lee new added function/// Returns:// A new autoreleased NSString with Base64 encoded NSString

+(NSString *)stringByBase64String:(NSString *)base64String

{

    NSString *sourceString = [[[NSString alloc] initWithData:[GTMBase64 decodeData:[base64String dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO]] encoding:NSUTF8StringEncoding] autorelease];

    return sourceString;

}

// David Lee new added function/// Returns:// A new autoreleased Base64 encoded NSString with NSString

+(NSString *)base64StringBystring:(NSString *)string

{

    NSString *base64String = [[[NSString alloc] initWithData:[GTMBase64 encodeData:[string dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO]] encoding:NSUTF8StringEncoding] autorelease];

    return base64String;

}

@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) {

        NSAssert(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?

        NSAssert(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.

            NSAssert(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) {

                NSAssert(destLen >= 2, @"our calc for encoded length was wrong");

                curDest[0] = kBase64PaddingChar;

                curDest[1] = kBase64PaddingChar;

                curDest += 2;

            }

            break;

        case 2:

            // Two bytes left: this encodes to three characters, and (optionally)

            // one pad character to round out the four-character cypherblock.

            NSAssert(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) {

                NSAssert(destLen >= 1, @"our calc for encoded length was wrong");

                curDest[0] = kBase64PaddingChar;

                curDest += 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.

                NSAssert(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.

                NSAssert((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.

                NSAssert((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.

                NSAssert(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

以上代码参考以下地址收集整理修改:

http://zxs19861202.iteye.com/blog/1980655              

AndroidiPhoneJava三个平台一致的加密方法

http://blog.sina.com.cn/s/blog_ad4920b70101lqqy.html   PHP3DES加解密类 兼容JAVA

https://github.com/isaced/GTMBase64     ios 字符串的base64编解码


3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。 最早的定义了该算法的标准(ANS X9.52,1998年发布)将其描述为“三重数据加密算法(TDEA)”— 即为ANSI X3.92中定义的数据加密算法(DEA)的三次重复操作— 而完全没有使用术语“3DES”或“DES”。FIPS PUB 46-3(1999)定义了“三重数据加密算法”(TDEA),也使用了术语“Triple DES”和“DES”。该标准中互换的使用“数据加密算法”(DEA)和“DES”的概念,其中以此开始DES的定义: 数据加密标准(DES)应当包括下文中的数据加密算法(DES[4])与三重数据加密算法(TDEA,如ANSI X9.52中所描述的) NIST SP 800-67(2004,2008[5])主要使用术语TDEA,但也提到了“Triple DES(TDEA)”。ISO/IEC 18033-3(2005)使用“TDEA”,但其中提到: TDEA通称Triple DES(数据加密标准)。 没有一个定义了本算法的标准使用术语“3DES”。 3DESughhhg34465345556555678==算法== 3DES使用“密钥包”,其包含3个DES密钥,K1,K2和K3,均为56位(除去奇偶校验位)。加密算法为: 密文 = EK3(DK2(EK1(平文))) 也就是说,使用K1为密钥进行DES加密,再用K2为密钥进行DES解密”,最后以K3进行DES加密。 而解密则为其反过程: 平文 = DK1(EK2(DK3(密文))) 即以K3解密,以K2“加密”,最后以K1解密。 每次加密操作都只处理64位数据,称为一块。 无论是加密还是解密,中间一步都是前后两步的逆。这种做法提高了使用密钥选项2时的算法强度,并在使用密钥选项3时与DES兼容。 密钥选项[编辑] 标准定义了三种密钥选项: 密钥选项1:三个密钥是独立的。 密钥选项2:K1和K2是独立的,而K3=K1 密钥选项3:三个密钥均相等,即K1=K2=K3 密钥选项1的强度最高,拥有3 x 56 = 168个独立的密钥位。 密钥选项2的安全性稍低,拥有2 x 56 = 112个独立的密钥位。该选项比简单的应用DES两次的强度较高,即使用K1和K2,因为它可以防御中途相遇攻击。 密钥选项3等同与DES,只有56个密钥位。这个选项提供了与DES的兼容性,因为第1和第2次DES操作相互抵消了。该选项不再为国家标准科技协会(NIST)所建议[6],亦不为ISO/IEC 18033-3所支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值