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方法(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持硕编程。
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!