欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

php、java、android、ios通用的3des方法(推荐)

程序员文章站 2024-02-28 14:56:28
php服务器,java服务器,android,ios开发兼容的3des加密解密, php

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

php

<?php
class 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://jb51.net的博客") . "\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://jb51.net的博客";
  	 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;
}

以上这篇php、java、android、ios通用的3des方法(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。