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

  

 




posted @ 2022-11-09 11:43  耿通宇  阅读(773)  评论(0编辑  收藏  举报