gpt4 book ai didi

c - 字节序无关的 base64_encode/decode 函数

转载 作者:太空宇宙 更新时间:2023-11-04 02:29:55 24 4
gpt4 key购买 nike

我在谷歌上搜索了这两个我碰巧需要的 C 函数,我遇到的最干净的是 http://fm4dd.com/programming/base64/base64_stringencode_c.htm 但在我看来它就像下面的一小部分......

void decodeblock(unsigned char in[], char *clrstr) {
unsigned char out[4];
out[0] = in[0] << 2 | in[1] >> 4;
out[1] = in[1] << 4 | in[2] >> 2;
out[2] = in[2] << 6 | in[3] >> 0;
out[3] = '\0';
strncat(clrstr, out, sizeof(out));
}

...将依赖字节序(同上,您可以在上面的网址中看到相应的 encodeblack())。但它在其他方面很好很干净,不像其他一些:一个有自己的三个头文件,另一个调用它自己的特殊 malloc()-like 函数,等等。任何人都知道一个漂亮、小、干净(没有头文件,没有依赖项等) 版本,像这个,更独立于体系结构?

编辑 我正在寻找这个的原因是 base64_encode() 将在作为 html 页面一部分的 php 脚本中完成,将编码的字符串传递给远程执行的 cgi 程序 -离开框。然后那个 cgi 必须对其进行 base64_decode()。因此,体系结构独立性只是增加了安全性,以防万一 cgi 在非英特尔大端盒(英特尔的小盒)上运行。

根据下面的评论编辑,这是完整的代码以及我所做的一些更改...

/* downloaded from...
http://fm4dd.com/programming/base64/base64_stringencode_c.htm */
/* ------------------------------------------------------------------------ *
* file: base64_stringencode.c v1.0 *
* purpose: tests encoding/decoding strings with base64 *
* author: 02/23/2009 Frank4DD *
* *
* source: http://base64.sourceforge.net/b64.c for encoding *
* http://en.literateprograms.org/Base64_(C) for decoding *
* ------------------------------------------------------------------------ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* ---- Base64 Encoding/Decoding Table --- */
char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/* decodeblock - decode 4 '6-bit' characters into 3 8-bit binary bytes */
void decodeblock(unsigned char in[], char *clrstr) {
unsigned char out[4];
out[0] = in[0] << 2 | in[1] >> 4;
out[1] = in[1] << 4 | in[2] >> 2;
out[2] = in[2] << 6 | in[3] >> 0;
out[3] = '\0';
strncat(clrstr, out, sizeof(out));
} /* --- end-of-function decodeblock() --- */

char *base64_decode(char *b64src /*, char *clrdst */) {
static char clrdstbuff[8192];
char *clrdst = clrdstbuff;
int c, phase, i;
unsigned char in[4];
char *p;

clrdst[0] = '\0';
phase = 0; i=0;
while(b64src[i]) {
c = (int) b64src[i];
if(c == '=') {
decodeblock(in, clrdst);
break; }
p = strchr(b64, c);
if(p) {
in[phase] = p - b64;
phase = (phase + 1) % 4;
if(phase == 0) {
decodeblock(in, clrdst);
in[0]=in[1]=in[2]=in[3]=0; }
} /* --- end-of-if(p) --- */
i++;
} /* --- end-of-while(b64src[i]) --- */
return ( clrdstbuff );
} /* --- end-of-function base64_decode() --- */

/* encodeblock - encode 3 8-bit binary bytes as 4 '6-bit' characters */
void encodeblock( unsigned char in[], char b64str[], int len ) {
unsigned char out[5];
out[0] = b64[ in[0] >> 2 ];
out[1] = b64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
out[2] = (unsigned char) (len > 1 ? b64[ ((in[1] & 0x0f) << 2) |
((in[2] & 0xc0) >> 6) ] : '=');
out[3] = (unsigned char) (len > 2 ? b64[ in[2] & 0x3f ] : '=');
out[4] = '\0';
strncat(b64str, out, sizeof(out));
} /* --- end-of-function encodeblock() --- */

/* encode - base64 encode a stream, adding padding if needed */
char *base64_encode(char *clrstr /*, char *b64dst */) {
static char b64dstbuff[8192];
char *b64dst = b64dstbuff;
unsigned char in[3];
int i, len = 0;
int j = 0;

b64dst[0] = '\0';
while(clrstr[j]) {
len = 0;
for(i=0; i<3; i++) {
in[i] = (unsigned char) clrstr[j];
if(clrstr[j]) {
len++; j++; }
else in[i] = 0;
} /* --- end-of-for(i) --- */
if( len ) {
encodeblock( in, b64dst, len ); }
} /* --- end-of-while(clrstr[j]) --- */
return ( b64dstbuff );
} /* --- end-of-function base64_encode() --- */

#ifdef TESTBASE64
int main( int argc, char *argv[] ) {
char *mysrc = (argc>1? argv[1] : "My bonnie is over the ocean ");
char *mysrc2 = (argc>2? argv[2] : "My bonnie is over the sea ");
char myb64[2048]="", myb642[2048]="";
char mydst[2048]="", mydst2[2048]="";
char *base64_enclode(), *base64_decode();
int testnum = 1;
if ( strncmp(mysrc,"test",4) == 0 )
testnum = atoi(mysrc+4);

if ( testnum == 1 ) {
strcpy(myb64,base64_encode(mysrc));
printf("The string [%s]\n\tencodes into base64 as: [%s]\n",mysrc,myb64);
strcpy(myb642,base64_encode(mysrc2));
printf("The string [%s]\n\tencodes into base64 as: [%s]\n",mysrc2,myb642);
printf("...\n");
strcpy(mydst,base64_decode(myb64));
printf("The string [%s]\n\tdecodes from base64 as: [%s]\n",myb64,mydst);
strcpy(mydst2,base64_decode(myb642));
printf("The string [%s]\n\tdecodes from base64 as: [%s]\n",myb642,mydst2);
} /* --- end-of-if(testnum==1) --- */

if ( testnum == 2 ) {
strcpy(mydst,base64_decode(mysrc2)); /* input is b64 */
printf("The string [%s]\n\tdecodes from base64 as: [%s]\n",mysrc2,mydst);
} /* --- end-of-if(testnum==2) --- */

if ( testnum == 3 ) {
int itest, ntests = (argc>2?atoi(argv[2]):999);
int ichar, nchars = (argc>3?atoi(argv[3]):128);
unsigned int seed = (argc>4?atoi(argv[4]):987654321);
char blanks[999] = " ";
srand(seed);
for ( itest=1; itest<=ntests; itest++ ) {
for ( ichar=0; ichar<nchars; ichar++ ) mydst[ichar] = 1+(rand()%255);
mydst[nchars] = '\000';
if ( strlen(blanks) > 0 ) strcat(mydst,blanks);
strcpy(myb64,base64_encode(mydst));
strcpy(mydst2,base64_decode(myb64));
if ( strcmp(mydst,mydst2) != 0 )
printf("Test#%d:\n\t in=%s\n\tout=%s\n",itest,mydst,mydst2);
} /* --- end-of-for(itest) --- */
} /* --- end-of-if(testnum==3) --- */

return 0;
} /* --- end-of-function main() --- */
#endif

最佳答案

不,它不依赖字节序。 Base64本身就是4字节到3字节的编码,并不关心内存中的实际表示。但是,如果您希望传输小/大端数据,则必须在编码之前和解码之后 规范化字节序。

该片段只是独立地寻址所有字节。如果它在 uint32_t 中加载 4 个字节,并且使用一些位旋转产生一个输出,它将按原样复制到结果缓冲区中,这将是字节序相关的。


然而,该代码的 strncat 很危险,并且无法处理嵌入的 NUL 字节。相反,你应该使用类似的东西

void decodeblock(unsigned char in[], unsigned char **clrstr) {
*((*clrstr) ++) = in[0] << 2 | in[1] >> 4;
*((*clrstr) ++) = in[1] << 4 | in[2] >> 2;
*((*clrstr) ++) = in[2] << 6 | in[3] >> 0;
}

这将适用于嵌入式 NUL。

关于c - 字节序无关的 base64_encode/decode 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44754836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com