当前位置: 移动技术网 > IT编程>开发语言>PHP > php、java、android、ios通用的3des方法(推荐)

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

2017年12月12日  | 移动技术网IT编程  | 我要评论

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方法(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网