主要是防止“iIlLoO0”在不同字体显示时做不是错,将其转为"<@#$%&*>"从而方便人员识别;
QT SDK 部份
//const char alphabet_base64[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
// "ghijklmn" "opqrstuv" "wxyz0123" "456789+/";
//const char alphabet_base64url[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
// "ghijklmn" "opqrstuv" "wxyz0123" "456789-_";
static const char *__replaceCheckChar[]={"iIlLoO0\0","[@#$%&,]\0"};
#define _D_CHECK_CHAR_REPLACE( byte, before, after ) \
if( !byte.isEmpty() ) \
for( int i = 0 ; before[i]!='\0' && after[i]!='\0'; i++ ) \
byte.replace( before[i], after[i] );
#define _D_BASE_CHAR_REPLACE(src) _D_CHECK_CHAR_REPLACE( src, __replaceCheckChar[0],__replaceCheckChar[1] ); src.push_front(':')
#define _D_BASE_CHAR_RESUME(src) if( !src.isEmpty() && src[0]==':' ) {src.remove(0,1); _D_CHECK_CHAR_REPLACE( src, __replaceCheckChar[1],__replaceCheckChar[0] );}
以下是测试为其他 IDE SDK与编写
#include <QCoreApplication>
#include <qdebug.h>
///数据转字符串
const char *_const_10tune64 = "0123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz@#$%";
const char *_10tune64_20 = "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz@#=%!,;+-";
unsigned char _64tune10_20[256] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x3B, 0xFF, 0x38, 0xFF, 0x3A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0x3C, 0x3F, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xFF, 0x3D, 0xFF, 0x39, 0xFF, 0xFF,
0x37, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0x10, 0x11, 0x12, 0x13, 0x14, 0xFF,
0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0xFF, 0x28, 0x29, 0xFF, 0x2A, 0x2B, 0xFF,
0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
const unsigned char _64tune10A_20[] = {
0xFF, 0x3B, 0xFF, 0x38, 0xFF, 0x3A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0x3C, 0x3F, 0xFF, 0xFF,
0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xFF, 0x3D, 0xFF, 0x39, 0xFF, 0xFF,
0x37, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0x10, 0x11, 0x12, 0x13, 0x14, 0xFF,
0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0xFF, 0x28, 0x29, 0xFF, 0x2A, 0x2B, 0xFF,
0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
const uchar _const_64tune10[256] = {
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,61,62,63,255,255,255,255,255,255,255,255,
255,255,0,1,2,3,4,5,6,7,8,9,255,255,255,255,255,255,60,10,11,
12,13,14,15,16,17,18,19,20,21,22,23,255,24,25,26,27,28,29,30,
31,32,33,34,255,255,255,255,255,255,35,36,37,38,39,40,41,42,
43,44,45,255,46,47,48,49,50,51,52,53,54,55,56,57,58,59,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255 };
static uchar *const_64tune10 =(uchar *)_64tune10_20;
static uchar *const_10tune64 =(uchar *)_10tune64_20;
// makeDecode生成解释特定字串的数组
void makeDecode( unsigned char *_64tune10,
unsigned char size,
const unsigned char _10tune64_20[64] )
{
memset( _64tune10, 0xff, size );
for(int k=0;k<64;k++)
{
_64tune10[ _10tune64_20[k] ]=(unsigned char)k;
}
// QString str("const unsigned char _64tune10_20[256] = {");
// for(int i=0;i<256;i++)
// {
// if( i%16==0 )
// str+="\n";
// str+=QString::asprintf("0x%0.2X, ", _64tune10[i]);
// }
// str+="};\n\n";
// qDebug()<<str;
}
// tByteTo64 将2进制数据转特定字符串
inline std::string tByteTo64( const int8_t* dat, const int size ) // 2进制转64
{
std::string str;
uint16_t val;
uint8_t *p=(uint8_t*)dat;
uint16_t ch=0;
for ( int count_ch=0,count_bit=0; count_ch<size || ch>0; )
{
if(count_ch<size && count_bit<6)
{
val = p[count_ch];
ch |= val<<count_bit;
count_bit+=8;
}
str.push_back( const_10tune64[ch & 0x3f] );
ch>>=6;
count_bit-=6;
if(count_bit<6) count_ch++;
}
return str;
}
inline std::string tByteTo64( std::vector<int8_t> dat ){
return tByteTo64( (const int8_t*) dat.data(), (const int) (dat.size()) );
}
inline std::string tByteTo64( std::vector<uint8_t> dat ){
return tByteTo64( (const int8_t*) dat.data(), (const int) (dat.size()) );
}
inline std::string tByteTo64( std::vector<int16_t> dat ){
return tByteTo64( (const int8_t*) dat.data(), (const int) (dat.size()*2) );
}
inline std::string tByteTo64( std::vector<uint16_t> dat ){
return tByteTo64( (const int8_t*) dat.data(), (const int) (dat.size()*2) );
}
inline std::string tByteTo64( std::vector<int32_t> dat ){
return tByteTo64( (const int8_t*) dat.data(), (const int) (dat.size()*4) );
}
inline std::string tByteTo64( std::vector<uint32_t> dat ){
return tByteTo64( (const int8_t*) dat.data(), (const int) (dat.size()*4) );
}
inline std::string tByteTo64( std::vector<int64_t> dat ){
return tByteTo64( (const int8_t*) dat.data(), (const int) (dat.size()*8) );
}
inline std::string tByteTo64( std::vector<uint64_t> dat ){
return tByteTo64( (const int8_t*) dat.data(), (const int) (dat.size()*8) );
}
inline std::string tByteTo64( std::vector<float> dat ){
return tByteTo64( (const int8_t*) dat.data(), (const int) (dat.size()*4) );
}
inline std::string tByteTo64( std::vector<double> dat ){
return tByteTo64( (const int8_t*) dat.data(), (const int) (dat.size()*8) );
}
inline std::string tByteTo64( uint8_t dat ){
return tByteTo64( (const int8_t*) &dat, (const int) sizeof(dat) );
}
inline std::string tByteTo64( int8_t dat ){
return tByteTo64( (const int8_t*) &dat, (const int) sizeof(dat) );
}
inline std::string tByteTo64( uint16_t dat ){
return tByteTo64( (const int8_t*) &dat, (const int) sizeof(dat) );
}
inline std::string tByteTo64( int16_t dat ){
return tByteTo64( (const int8_t*) &dat, (const int) sizeof(dat) );
}
inline std::string tByteTo64( uint32_t dat ){
return tByteTo64( (const int8_t*) &dat, (const int) sizeof(dat) );
}
inline std::string tByteTo64( int32_t dat ){
return tByteTo64( (const int8_t*) &dat, (const int) sizeof(dat) );
}
inline std::string tByteTo64( uint64_t dat ){
return tByteTo64( (const int8_t*) &dat, (const int) sizeof(dat) );
}
inline std::string tByteTo64( int64_t dat ){
return tByteTo64( (const int8_t*) &dat, (const int) sizeof(dat) );
}
inline std::string tByteTo64( float dat ){
return tByteTo64( (const int8_t*) &dat, (const int) sizeof(dat) );
}
inline std::string tByteTo64( double dat ){
return tByteTo64( (const int8_t*) &dat, (const int) sizeof(dat) );
}
// t64ToByte 将特定字符串转为2进制数据
bool t64ToByte( const std::string p , char* dat, int &len )//64进制转2
{
int iSize=len;
int i=0;
qint16 j=0;
int val=0;
int size = p.size();
int k=0;
len=0;
for ( ; i<size && len<iSize; i++ )
{
j = (uchar)const_64tune10 [ p.at(i) ];
if ( j == 255 )
{
len=-1;
return false;
}
val |= (j<<(k));
k+=6;
for( ; k>=8 && len<iSize; )
{
dat[ len++ ]=val&0xff;
val>>=8;
k-=8;
}
}
len++;
return true;
}
#define _D_64TO_BYTE_VECTOR_HELPER( ty ) \
int si=p.size()*6; \
int len = (si/8)+(si%8!=0? 1:0); \
char* data=new char[ len ]; \
ty *pd=( ty *)data; \
bool ok = t64ToByte( p, (char*) data, len ); \
if(ok) { \
for( int i=0,j=len/sizeof(ty); i<j; i++ ) \
dat.push_back( pd[i]); } \
return ok;
#define _D_64TO_BYTE_HELPER( ) \
int len=sizeof(dat); \
bool ok = t64ToByte( p, (char*) &dat, len ); \
return ok;
inline bool t64ToByte( const std::string p , std::vector<int8_t> &dat ){
_D_64TO_BYTE_VECTOR_HELPER( int8_t );
}
inline bool t64ToByte( const std::string p , std::vector<uint8_t> &dat ){
_D_64TO_BYTE_VECTOR_HELPER( uint8_t );
}
inline bool t64ToByte( const std::string p , std::vector<int16_t> &dat ){
_D_64TO_BYTE_VECTOR_HELPER( int16_t );
}
inline bool t64ToByte( const std::string p , std::vector<uint16_t> &dat ){
_D_64TO_BYTE_VECTOR_HELPER( uint16_t );
}
inline bool t64ToByte( const std::string p , std::vector<int32_t> &dat ){
_D_64TO_BYTE_VECTOR_HELPER( int32_t );
}
inline bool t64ToByte( const std::string p , std::vector<uint32_t> &dat ){
_D_64TO_BYTE_VECTOR_HELPER( uint32_t );
}
inline bool t64ToByte( const std::string p , std::vector<int64_t> &dat ){
_D_64TO_BYTE_VECTOR_HELPER( int64_t );
}
inline bool t64ToByte( const std::string p , std::vector<uint64_t> &dat ){
_D_64TO_BYTE_VECTOR_HELPER( uint64_t );
}
inline bool t64ToByte( const std::string p , std::vector<float> &dat ){
_D_64TO_BYTE_VECTOR_HELPER( float );
}
inline bool t64ToByte( const std::string p , std::vector<double> &dat ){
_D_64TO_BYTE_VECTOR_HELPER( double );
}
inline bool t64ToByte( const std::string p , uint8_t &dat ){
_D_64TO_BYTE_HELPER();
}
inline bool t64ToByte( const std::string p , int8_t &dat ){
_D_64TO_BYTE_HELPER();
}
inline bool t64ToByte( const std::string p , uint16_t &dat ){
_D_64TO_BYTE_HELPER();
}
inline bool t64ToByte( const std::string p , int16_t &dat ){
_D_64TO_BYTE_HELPER();
}
inline bool t64ToByte( const std::string p , uint32_t &dat ){
_D_64TO_BYTE_HELPER();
}
inline bool t64ToByte( const std::string p , int32_t &dat ){
_D_64TO_BYTE_HELPER();
}
inline bool t64ToByte( const std::string p , uint64_t &dat ){
_D_64TO_BYTE_HELPER();
}
inline bool t64ToByte( const std::string p , int64_t &dat ){
_D_64TO_BYTE_HELPER();
}
inline bool t64ToByte( const std::string p , float &dat ){
_D_64TO_BYTE_HELPER();
}
inline bool t64ToByte( const std::string p , double &dat ){
_D_64TO_BYTE_HELPER();
}
// t64ToByte 将特定字符串转为2进制数据
bool t64ToByte( const QByteArray p , QByteArray &dat )//64进制转2
{
int i=0;
qint16 j=0;
int val=0;
int size = p.size();//419d747fe0000000
int k=0;
for ( ; i<size ; i++ )
{
j = (uchar)const_64tune10 [ p.at(i) ];
if ( j == 255 )
{
dat.clear();
return false;
}
val |= (j<<(k));
k+=6;
for( ; k>=8 ; )
{
dat.append( val&0xff );
val>>=8;
k-=8;
}
}
return true;
}
// tByteTo64 将2进制数据转特定字符串
QByteArray tByteTo64( const QByteArray dat ) // 2进制转64
{
int size = dat.size() ;
QByteArray str;
uint16_t val;
uint8_t *p = (uint8_t*)dat.data();
int j=0;
uint16_t ch=0;
for ( int c=0,bi=0;c<size || ch>0; )
{
if(c<size && bi<6)
{
val=p[c];
ch|=val<<bi;
bi+=8;
}
j = ch & 0x3f;
str.push_back( const_10tune64[j]);
ch>>=6;
bi-=6;
if(bi<6)c++;
}
return str;
}
// t64ToByte 将特定字符串转为2进制数据
QByteArray t64ToByte( const QByteArray p )//64进制转2
{
QByteArray dat;
bool ok=t64ToByte( p , dat );
return dat;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
makeDecode( const_64tune10, 256, const_10tune64 );
std::vector<int64_t> dat,dat2;
int k=0;
for( int i=0; i<100; i++ ) {
k = qrand()*100;
dat.push_back(k);
}
std::string str = tByteTo64( dat );
qDebug()<<__LINE__<< str.data()<< str.size()<<(str.size()*6/8)+(str.size()*6%8!=0? 1:0);
qDebug()<<__LINE__<< t64ToByte( str , dat2 );
for(int i=0;i<100;i++){
qDebug()<<__LINE__<<"\t\t"<<i<<"\t\t"<< dat.at(i)<<"\t\t"<< dat2.at(i)<<"\t\t"<<(dat.at(i) - dat2.at(i));
}
return a.exec();
}