C语言编写base32编码解码代码实现

一、什么是Base32

Base32编码是使用32个可打印字符(字母A-Z和数字2-7)对任意字节数据进行编码的方案,编码后的字符串不用区分大小写并排除了容易混淆的字符,可以方便地由人类使用并由计算机处理。

二、编码方法

将任意字符串按照字节进行切分,并将每个字节对应的二进制值(不足8比特高位补0)串联起来,按照5比特一组进行切分,并将每组二进制值转换成十进制来对应32个可打印字符中的一个。

32是2的5次方,在进行2进制截位时,要一次截取5位。那么一个字节8位,截取了5位,剩下的3位怎么办?同理和下一个字节的前2位组成一个新的5位。那么多少个字节按照5位截取才能不丢位呢?我们要取5和8的最小公倍数,40位,按照5位截取,正好得到8个编码。

三、C语言实现的编码解码

废话不多说,上代码,该代码可直接运行

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>

// Base32字符表
static const char base32_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";


#define MIN(a, b) (((a) < (b)) ? (a) : (b))

// Base32编码函数
int base32_encode(char *dest, int destlen_chars,const void *srcbits, int srclen_bits) {
    const uint8_t *src = srcbits;
    int destlen_needed;
    int didx = 0;
    int i;
    *dest = 0;
    /* Make sure destination is big enough */
    destlen_needed = (srclen_bits + 4) / 5;  /* Symbols before adding CRC */
    destlen_needed++;  /* For terminating null */
    if (destlen_chars < destlen_needed)
        return -1; // Error: Destination buffer too small
    for (i = 0; i < srclen_bits; i += 5) {
        int sym;
        int sidx = i / 8;
        int bit_offs = i % 8;
        if (bit_offs <= 3) {
            /* Entire symbol fits in that byte */
            sym = src[sidx] >> (3 - bit_offs);
        } else {
            /* Use the bits we have left */
            sym = src[sidx] << (bit_offs - 3);
            /* Use the bits from the next byte, if any */
            if (i + 1 < srclen_bits)
                sym |= src[sidx + 1] >> (11 - bit_offs);
        }
        sym &= 0x1f;
        /* Pad incomplete symbol with 0 bits */
        if (srclen_bits - i < 5)
            sym &= 0x1f << (5 + i - srclen_bits);
        dest[didx++] = base32_table[sym];
    }
    /* Calculate the number of padding characters needed */
    int padding = (8 - (didx % 8)) % 8;
    /* Pad the remaining characters with '=' */
    for (i = 0; i < padding; i++) {
        dest[didx++] = '=';
    }
    /* Terminate string and return */
    dest[didx] = 0;
    return 0; // Success
}




static int decode_sym(char c) {
    if (c >= 'A' && c <= 'Z')
        return c - 'A';
    if (c >= '2' && c <= '7')
        return c - '2' + 26;
    return -1;
}

static int crc5_sym(int sym, int crc) {
    return (crc << 5) ^ sym;
}

int base32_decode(uint8_t *dest, int destlen_bits, const char *src, int crc_after_every) {
    int crc = 0, crc_count = 0;
    int out_bits = 0;
    
    for (; *src; src++) {
        int sym, sbits, dbits, b;
        
        if (isspace(*src) || *src == '-')
            continue;
        
        sym = decode_sym(*src);
        if (sym < 0)
            return -1;  /* Bad input symbol */
        
        /* Check CRC if needed */
        if (crc_after_every) {
            if (crc_count == crc_after_every) {
                if (crc != sym)
                    return -1;
                crc_count = crc = 0;
                continue;
            } else {
                crc = crc5_sym(sym, crc);
                crc_count++;
            }
        }
        
        /* Stop if we're out of space */
        if (out_bits >= destlen_bits)
            break;
        
        /* See how many bits we get to use from this symbol */
        sbits = MIN(5, destlen_bits - out_bits);
        if (sbits < 5)
            sym >>= (5 - sbits);
        
        /* Fill up the rest of the current byte */
        dbits = 8 - (out_bits & 7);
        b = MIN(dbits, sbits);
        
        if (dbits == 8)
            dest[out_bits / 8] = 0;  /* Starting a new byte */
        
        dest[out_bits / 8] |= (sym << (dbits - b)) >> (sbits - b);
        out_bits += b;
        sbits -= b;
        
        /* Start the next byte if there's space */
        if (sbits > 0) {
            dest[out_bits / 8] = sym << (8 - sbits);
            out_bits += sbits;
        }
    }
    
    /* If we have CRCs, should have a full group */
    if (crc_after_every && crc_count)
        return -1;
    
    return out_bits;
}


int main() {

    const char *input = "Hello,World!";
    char output[100];

    // 编码 "Hello" 的 Base32 值
    int ret = base32_encode(output, sizeof(output), input, strlen(input) * 8);

    if (ret == 0) {
        printf("Base32 encoded string: %s\n", output);
    } else {
        printf("Error: Base32 encoding failed.\n");
    }

    const char *base32_encoded_string = "JBSWY3DPFRLW64TMMQQQ";
    uint8_t decoded_data[20]; // Adjust the size accordingly
    int decoded_bits = base32_decode(decoded_data, sizeof(decoded_data) * 8, base32_encoded_string, 0);
    
    if (decoded_bits == -1) {
        printf("Error decoding Base32 string.\n");
        return 1;
    }
    
    printf("Decoded data: ");
    for (int i = 0; i < decoded_bits / 8; i++) {
        printf("%c", decoded_data[i]);
    }
    printf("\n");
    
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值