大家好,欢迎来到IT知识分享网。
一、什么是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[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; #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 = "JBSWY3DPFRLW64TMMQ"; 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; }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/120094.html