编码:
/*
*inHex:输入参数,待编码十六进制数据首地址,如果NULL表示计算输出需要缓冲大小
*inBytes:输入参数,待编码十六进制数据字节长度,如果<=0表示计算输出需要缓冲大小
*outStr:输出参数,编码之后的字符串数据
*outBufLen:输入参数,编码出来的缓存字节
*返回值:>=0表示成功编码,编码后数据长度;<0表示出错
*/
int Base64Encode(char* inHex, int inBytes, char* outStr, int outBufLen)
{
/* A-Z a-z 0-9 +/ */
int i = 0;
int charIndex = 0;
switch (inBytes % 3) {
case 0:
i = (i / 3) * 4;
break;
case 1:
i = (i / 3) * 4 + 1 + 1;
i = i + 2;
break;
case 2:
i = (i / 3) * 4 + 1 + 1 + 1;
i = i + 1;
break;
}
if (outStr == NULL || outBufLen <= 0) {
i++;
goto EXIT_FUN;
}
if (i >= outBufLen) {
/* 缓冲不够 */
i = -1;
goto EXIT_FUN;
}
charIndex = 0;
for (i = 0; i < inBytes; i++) {
switch (i % 3) {
case 0:
charIndex = inHex[i] >> 2;
break;
case 1:
charIndex = inHex[i - 1] << 4;
charIndex &= 0x00000030;
charIndex |= (inHex[i] >> 4) & 0x0F;
break;
case 2:
charIndex = inHex[i - 1] << 2;
charIndex &= 0x0000003C;
charIndex |= (inHex[i] >> 6) & 0x03;
break;
default:
break;
}
charIndex &= 0x0000003F;
if (charIndex >= 0 && charIndex < 26) {
outStr[(i / 3) * 4 + (i % 3)] = 'A' + charIndex;
} else if (charIndex >= 26 && charIndex < 52) {
outStr[(i / 3) * 4 + (i % 3)] = 'a' + charIndex - 26;
} else if (charIndex >= 52 && charIndex < 62) {
outStr[(i / 3) * 4 + (i % 3)] = '0' + charIndex - 52;
} else if (charIndex == 62) {
outStr[(i / 3) * 4 + (i % 3)] = '+';
} else if (charIndex == 63) {
outStr[(i / 3) * 4 + (i % 3)] = '/';
}
if ((i % 3) == 2 || i + 1 >= inBytes) {
if ((i % 3) == 2) {
charIndex = inHex[i];
charIndex &= 0x0000003F;
} else if ((i % 3) == 0) {
charIndex = inHex[i] << 4;
charIndex &= 0x00000030;
} else if ((i % 3) == 1) {
charIndex = inHex[i] << 2;
charIndex &= 0x0000003C;
}
if (charIndex >= 0 && charIndex < 26) {
outStr[(i / 3) * 4 + (i % 3) + 1] = 'A' + charIndex;
} else if (charIndex >= 26 && charIndex < 52) {
outStr[(i / 3) * 4 + (i % 3) + 1] = 'a' + charIndex - 26;
} else if (charIndex >= 52 && charIndex < 62) {
outStr[(i / 3) * 4 + (i % 3) + 1] = '0' + charIndex - 52;
} else if (charIndex == 62) {
outStr[(i / 3) * 4 + (i % 3) + 1] = '+';
} else if (charIndex == 63) {
outStr[(i / 3) * 4 + (i % 3) + 1] = '/';
}
}
}
switch (inBytes % 3) {
case 0:
i = (i / 3) * 4;
break;
case 1:
i = (i / 3) * 4 + 1 + 1;
strcpy(outStr + i, "==");
i = i + 2;
break;
case 2:
i = (i / 3) * 4 + 1 + 1 + 1;
strcpy(outStr + i, "=");
i = i + 1;
break;
}
outStr[i] = 0;
EXIT_FUN:
return i;
}
解码:
/*
*inStr:输入参数,待解码字符串数据首地址,如果NULL表示计算输出需要缓冲大小
*outHex:输出参数,解码之后的十六进制数据
*outBufLen:输入参数,解码出来的缓存字节
*返回值:>=0表示成功编码,编码后数据长度;<0表示出错
*/
int Base64Decode(char* inStr, char* outHex, int outBufLen)
{
int i = 0;
int equalSignCnt = 0;
int inLen = strlen(inStr);
int charIndex = 0;
int validBase64Index = 0;
char tmp[4];
for (i = 0; i < inLen; i++) {
if (inStr[i] >= 'A' && inStr[i] <= 'Z') {
charIndex = inStr[i] - 'A';
} else if (inStr[i] >= 'a' && inStr[i] <= 'z') {
charIndex = inStr[i] - 'a' + 26;
} else if (inStr[i] >= '0' && inStr[i] <= '9') {
charIndex = inStr[i] - '0' + 52;
} else if (inStr[i] == '+') {
charIndex = 62;
} else if (inStr[i] == '/') {
charIndex = 63;
} else if (inStr[i] == '=') {
for (equalSignCnt = 0; i < inLen; i++) {
if (inStr[i] == '=') {
equalSignCnt++;
}
}
if (equalSignCnt > 2 || equalSignCnt < 1) {
/* 数据格式错误 */
i = -1;
goto EXIT_FUN;
}
break;
} else {
continue;
}
if (outHex == NULL || outBufLen <= 0) {
validBase64Index++;
continue;
}
switch (validBase64Index % 4) {
case 0:
tmp[0] = charIndex << 2;
tmp[0] &= (~0x03);
break;
case 1:
tmp[0] |= (charIndex >> 4);
tmp[1] = (charIndex << 4);
tmp[1] &= 0xF0;
break;
case 2:
tmp[1] |= (charIndex >> 2);
tmp[2] = charIndex << 6;
tmp[2] &= 0xC0;
break;
case 3:
tmp[2] |= charIndex;
if ((validBase64Index / 4) * 3 + 3 >= outBufLen) {
/* 缓冲不够 */
i = -1;
goto EXIT_FUN;
}
outHex[(validBase64Index / 4) * 3] = tmp[0];
outHex[(validBase64Index / 4) * 3 + 1] = tmp[1];
outHex[(validBase64Index / 4) * 3 + 2] = tmp[2];
break;
}
validBase64Index++;
}
if ((validBase64Index % 4) == 0) {
if (i >= inLen) {
i = (validBase64Index / 4) * 3;
goto EXIT_FUN;
}
/* 数据格式错误 */
i = -1;
goto EXIT_FUN;
}
/* if (inStr[i] == '=') */
if (equalSignCnt == 1) {
if (outHex != NULL && outBufLen > 0) {
if ((validBase64Index / 4) * 3 + 2 >= outBufLen) {
/* 缓冲不够 */
i = -1;
goto EXIT_FUN;
}
outHex[(validBase64Index / 4) * 3] = tmp[0];
outHex[(validBase64Index / 4) * 3 + 1] = tmp[1];
}
i = (validBase64Index / 4) * 3 + 2;
}
if (equalSignCnt == 2) {
if (outHex != NULL && outBufLen > 0) {
if ((validBase64Index / 4) * 3 + 1 >= outBufLen) {
/* 缓冲不够 */
i = -1;
goto EXIT_FUN;
}
outHex[(validBase64Index / 4) * 3] = tmp[0];
}
i = (validBase64Index / 4) * 3 + 1;
}
EXIT_FUN:
return i;
}