base32转ascii、base64转HEX
base32
一、简介:
Base32编码使用32个ASCII字符对任何数据进行编码,Base32与Base64的实现原理类似,同样是将原数据二进制形式取指定位数转换为ASCII码。首先获取数据的二进制形式,将其串联起来,每5个比特为一组进行切分,每一组内的5个比特可转换到指定的32个ASCII字符中的一个,将转换后的ASCII字符连接起来,就是编码后的数据。
二、字典:
Base32依赖更小的字典,Base32编码时每5个字符为一个分组,字典的长度为25 + 1=33。
Base32通用的字典定义如下:
案例:"ILU"字符串根据Base32编码进行编码,先根据ASCII编码得到对应字符编码值以及对应二进制,将所有二进制串起来,然后按照5个二进制位为一组分割 ,得到十进制值=>找到Base32编码表找到对应的字符.案例总共分割成了5组(25位),还差三组(15位).在末尾补充3个"=".经过Base32编码后最终值应是"JFGFK===".
Base32还提供了另外一种字典定义,即Base32十六进制字母表。Base32十六进制字母表是参照十六进制的计数规则定义:
因此在实际运用中需要区分具体使用的是那个字典编码方法。大多数用的是第一种。
三、示例源码
根据第一个字典的编码实现代码示例如下:代码来源Github
地址:https://github.com/synacktraa/base32,著作权归作者所有,转载请注明出处。
//=================================================_ // Base32 Encoding and Decoding Tool |_ // Author: @SynActktraa [Mikey] |_ // (Cli Wizard) base32 algorithm implemented in C. |_ // © This tool is based on ASCII charset. |_ //======================================================= #include<stdio.h> #include<string.h> #include<stdlib.h> #include"base32.h" int isLower(int ch){ if(ch >= 97 && ch <= 122) return 1; return 0 ; } int power(int base, int p){ int result = 1; if(p){ for(int i = p; i > 0; i--){ result *= base; } return result; } else{ return result; } } int Delete(char*data, int index, int length){ int i; for (i = index; i < (length)-1; i++){ *(data+i) = *(data+i+1); } *(data+i) = '\0'; length--; return length; } int insert(char*data, int index, int element, int uSize, int tSize){ if(uSize >= tSize) return -1; for(int i = uSize-1; i >= index; i--) *(data+i+1) = *(data+i); *(data+index) = element; uSize++; *(data+(uSize)) = '\0'; return uSize; } int binToDec(char* binary){ int i = 0, j, k; int dec = 0; while(*(binary+i) != '\0') ++i; for(j = i-1, k = 0; j >= 0; --j, ++k){ dec += (*(binary+k)-48)*power(2,j); } return dec; } void reverse(char*str){ int len = 0; char*ptr = str; while(*ptr != '\0'){ len++; ptr++; } int i = 0, j = len-1; while(i < j){ int temp = *(str+i); *(str+i) = *(str+j); *(str+j) = temp; ++i; --j; } } char* decToBin(int n){ unsigned int dec = n; char binary[20]; int i = 0; while(dec){ int remain = dec % 2; binary[i++] = remain+48; dec = dec/2; } binary[i] = '\0'; reverse(binary); return strdup(binary); } int charValidate(char ch) { if(ch < 0 || ch > 126) return -1; return 0; } /** * @brief base32编码 * * @param data 明文数据 * @param out 编码后的密文数据 * @return int 成功返回1,失败返回负数 */ int encode(char*indata,char* outdata){ int buffer_len; char* plaintext; plaintext = strdup(indata); buffer_len = strlen(plaintext); int base32_val_space = (0.65*(buffer_len+1))+buffer_len+2; int bin_dump_space = (buffer_len * 8)+1; char *base32_val = (char*)malloc(sizeof(char) * base32_val_space); char *bin_dump = (char*)malloc(sizeof(char) * bin_dump_space); char five_bit_bin[6], Ox49_val_bin[10]; int i, j, k, bin_dump_len; memset(Ox49_val_bin, 0, strlen(Ox49_val_bin)); memset(bin_dump, 0, strlen(bin_dump)); for(i=0; *(plaintext+i) != '\0'; ++i){ label: /* charValidate checks for non-ascii characters */ if( charValidate(plaintext[i]) == -1 ){ //fprintf(stderr, "InputError: can't take non-ascii characters."); //putc(ch, stdout); return -1;//exit(1); } /* checks for CR(carriage return) [this problem occurs in unix systems] if present it deletes CR at the current index and proceeds to continue from label. */ if (plaintext[i] == 13){ Delete(plaintext, i, strlen(plaintext)); goto label; } strcpy(Ox49_val_bin, decToBin(*(plaintext+i))); while(strlen(Ox49_val_bin)%8 != 0){ /* checks for 8 bit binary, if not it starts adding zeroes from the 0th index until it's 8 bit binary value. */ k = insert(Ox49_val_bin, 0, '0', strlen(Ox49_val_bin), strlen(Ox49_val_bin)+1); Ox49_val_bin[k] = '\0'; } //concatenates the 8 bit binary in bin_dump to create //a binary dump which will be manipulated later strcat(bin_dump, Ox49_val_bin); memset(Ox49_val_bin, 0, strlen(Ox49_val_bin)); } free(plaintext); bin_dump_len = strlen(bin_dump); while(bin_dump_len%5 != 0){ /* checks if the length of binary dump is in the multiplication of 5, coz base32 -> 2^5 = 32 */ bin_dump_len = insert(bin_dump, bin_dump_len, '0', bin_dump_len, strlen(bin_dump)+1); } i = 0, j = 0; while(*(bin_dump+i)!='\0'){ /* moves 6 bits from bin_dump to six_bit_bin, converts the 6 bit binary to decimal and stores it in ascii_val and do some comparisions, then adds accordingly and stores it in base64_val string and increments i by 6. */ memset(five_bit_bin, 0, strlen(five_bit_bin)); memmove(five_bit_bin, bin_dump+i, 5); int ascii_val = binToDec(five_bit_bin); if(ascii_val>=0 && ascii_val<=25) base32_val[j] = ascii_val+65; else if(ascii_val>=26 && ascii_val<=31) base32_val[j] = ascii_val+24; j++; i += 5; } base32_val[j] = '\0'; free(bin_dump); while(strlen(base32_val)%4 != 0) /* inserts '=' at the end of the base64 encoded string until the length is in the multiplication of 4. */ insert(base32_val, strlen(base32_val), 0x3d, strlen(base32_val), base32_val_space); strcpy(outdata,base32_val); free(base32_val); return 1; } /** * @brief base32解码 * * @param data 密文数据 * @param out 解密后的明文数据 * @return int 成功返回1,失败返回负数 */ int decode(char*indata,char* outdata){ int i, j; int buffer_len; char* base32_data; base32_data = strdup(indata); buffer_len = strlen(base32_data); // calculates space for base32 encoded string int decData_val_space = (buffer_len+2)-(0.12*buffer_len); // calculates space for binary dump of input string int bin_dump_space = (buffer_len * 6)+1; char Ox49_val_bin[10], byte_bin[10]; char *bin_dump = (char*)malloc(sizeof(char) * bin_dump_space); char *decodeData = (char*)malloc(sizeof(char) * decData_val_space); while(*(base32_data+(buffer_len-1)) == 0x3D){ /* checks for '=' from the end of the input encoded string and deletes the padding */ buffer_len = Delete(base32_data, buffer_len-1, buffer_len); } if(buffer_len == 1) return -1;//exit(1); for(i=0; base32_data[i]!=0; ++i){ if(isLower(base32_data[i]) || base32_data[i]=='0' || base32_data[i]==0x31 || base32_data[i]==0x38 || base32_data[i]==0x39){ //fprintf(stderr, "Error: Invalid base32 characters\n"); return -2;//exit(1); } } memset(bin_dump, 0, strlen(bin_dump)); memset(Ox49_val_bin, 0, strlen(Ox49_val_bin)); for(i=0; base32_data[i]!=0; ++i){ /* checks for encoded data simultaneously, then subtracts and evaluated decimal to binary function, then copies it in Ox49_val_bin */ if(base32_data[i]>='B' && base32_data[i]<='Z'){ strcpy(Ox49_val_bin, decToBin(base32_data[i]-65)); } else if(base32_data[i]>='2' && base32_data[i]<='7'){ strcpy(Ox49_val_bin, decToBin(base32_data[i]-24)); } else if(base32_data[i] == 'A') strcpy(Ox49_val_bin, "00000"); int k = strlen(Ox49_val_bin); while(strlen(Ox49_val_bin)%5 != 0) /* checks if the length of binary is in the multiplication of 5, coz base32 -> 2^5 = 32 */ k = insert(Ox49_val_bin, 0, '0', k, sizeof(Ox49_val_bin)); Ox49_val_bin[k] = '\0'; strcat(bin_dump, Ox49_val_bin); memset(Ox49_val_bin, 0, strlen(Ox49_val_bin)); } free(base32_data); int bin_dump_len = strlen(bin_dump); while(strlen(bin_dump)%8 != 0) /* checks for 8 bit binary, if not it starts adding zeroes from the 0th index until it's 8 bit binary value. */ bin_dump_len = insert(bin_dump, bin_dump_len, '0', bin_dump_len, bin_dump_space); *(bin_dump+bin_dump_len) = '\0'; i = 0, j = 0; while(*(bin_dump+i)!='\0'){ /* moves 1 byte from bin_dump to byte_bin, converts that byte binary to decimal and stores it in decodeData and increments i by 8. */ memset(byte_bin, 0, strlen(byte_bin)); memmove(byte_bin, bin_dump+i, 8); byte_bin[8] = 0; decodeData[j] = binToDec(byte_bin); j++; i += 8; } decodeData[j] = '\0'; strcpy(outdata,decodeData); free(bin_dump); free(decodeData); return 1; }
#ifndef BASE32_H /* Include guard */ #define BASE32_H int encode(char*indata,char* outdata);//编码 int decode(char*indata,char* outdata);//解码 #endif
base32在线转换工具:在线Base32编码加密解密工具-Bejson.com
base64
一、简介
Base64是基于(Base)64个字的一种二进制到文本的编码方式。即一种将 byte
数组编码为字符串的方法,编码后(除填充字符=外
)只包含64个ASCII码。Base64不是加密算法,只是一种编码方式,算法也是公开的,所以不能依赖它进行加密。base64加密后的"=="号中的 =
比较特殊,是填充符,即加密后字符不够64位用=填充。
二、字典
Base64使用到的64个字符:
A-Z
26个a-z
26个0-9
10个+
1个/
1个
下图是Base64码表,可以看到从0到63的每个数字都对应一个上面的一个字符。
三、示例源码(base64转HEX )
#include "base64.h" unsigned char *base64_encode(unsigned char *str,int strlen) { long len; long str_len; unsigned char *res; int i,j; //定义base64编码表 unsigned char *base64_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //计算经过base64编码后的字符串长度 str_len=strlen; if(str_len % 3 == 0) len=str_len/3*4; else len=(str_len/3+1)*4; res=malloc(sizeof(unsigned char)*len+1); res[len]='\0'; //以3个8位字符为一组进行编码 for(i=0,j=0;i<len-2;j+=3,i+=4) { res[i]=base64_table[str[j]>>2]; //取出第一个字符的前6位并找出对应的结果字符 res[i+1]=base64_table[(str[j]&0x3)<<4 | (str[j+1]>>4)]; //将第一个字符的后位与第二个字符的前4位进行组合并找到对应的结果字符 res[i+2]=base64_table[(str[j+1]&0xf)<<2 | (str[j+2]>>6)]; //将第二个字符的后4位与第三个字符的前2位组合并找出对应的结果字符 res[i+3]=base64_table[str[j+2]&0x3f]; //取出第三个字符的后6位并找出结果字符 } switch(str_len % 3) { case 1: res[i-2]='='; res[i-1]='='; break; case 2: res[i-1]='='; break; } return res; } unsigned char *base64_decode(unsigned char *code,int *codelen) { //根据base64表,以字符找到对应的十进制数据 int table[]={0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,62,0,0,0, 63,52,53,54,55,56,57,58, 59,60,61,0,0,0,0,0,0,0,0, 1,2,3,4,5,6,7,8,9,10,11,12, 13,14,15,16,17,18,19,20,21, 22,23,24,25,0,0,0,0,0,0,26, 27,28,29,30,31,32,33,34,35, 36,37,38,39,40,41,42,43,44, 45,46,47,48,49,50,51 }; long len; long str_len; unsigned char *res; int i,j; //计算解码后的字符串长度 len=strlen(code); //判断编码后的字符串后是否有= if(strstr(code,"==")) str_len=len/4*3-2; else if(strstr(code,"=")) str_len=len/4*3-1; else str_len=len/4*3; res=malloc(sizeof(unsigned char)*str_len+1); res[str_len]='\0'; *codelen=str_len; //以4个字符为一位进行解码 for(i=0,j=0;i < len-2;j+=3,i+=4) { res[j]=((unsigned char)table[code[i]])<<2 | (((unsigned char)table[code[i+1]])>>4); //取出第一个字符对应base64表的十进制数的前6位与第二个字符对应base64表的十进制数的后2位进行组合 res[j+1]=(((unsigned char)table[code[i+1]])<<4) | (((unsigned char)table[code[i+2]])>>2); //取出第二个字符对应base64表的十进制数的后4位与第三个字符对应bas464表的十进制数的后4位进行组合 res[j+2]=(((unsigned char)table[code[i+2]])<<6) | ((unsigned char)table[code[i+3]]); //取出第三个字符对应base64表的十进制数的后2位与第4个字符进行组合 } return res; }
#ifndef _BASE64_H #define _BASE64_H #include <stdlib.h> #include <string.h> unsigned char *base64_encode(unsigned char *str,int strlen); unsigned char *base64_decode(unsigned char *code,int *codelen); #endif
base64在线转换工具:Base64 到十六进制:在线编码和解码字节 - cryptii