我有一个二进制字符串,我在Base 64中编码。现在,我需要事先了解最终Base 64编码字符串的大小。
有没有办法计算出来?
类似的东西:
BinaryStringSize是64Kb 编码后,EncodedBinaryStringSize将为127Kb。
哦,代码在C中。
感谢。
答案 0 :(得分:31)
如果您执行Base64 exactly right,并且包括用=
字符填充结尾,并且每隔72个字符用CR LF
分解,则可以找到以下答案:
code_size = ((input_size * 4) / 3);
padding_size = (input_size % 3) ? (3 - (input_size % 3)) : 0;
crlfs_size = 2 + (2 * (code_size + padding_size) / 72);
total_size = code_size + padding_size + crlfs_size;
在C中,你也可以用\0
字节终止,因此那里会有一个额外的字节,你可能想要在编写每个代码的末尾进行长度检查,所以如果您只是在寻找传递给malloc()
的内容,您可能实际上更喜欢浪费几个字节的版本,以便使编码更简单:
output_size = ((input_size * 4) / 3) + (input_size / 96) + 6;
答案 1 :(得分:24)
geocar的答案很接近,但有时可能会稍微偏离。
每3个字节的输入有4个字节的输出。如果输入大小不是三的倍数,我们必须添加以使其成为一。否则不管它。
input_size + ( (input_size % 3) ? (3 - (input_size % 3)) : 0)
将其除以3,然后乘以4.这是我们的总输出大小,包括填充。
code_padded_size = ((input_size + ( (input_size % 3) ? (3 - (input_size % 3)) : 0) ) / 3) * 4
正如我在评论中所说,在加倍之前,总大小必须除以线宽,以正确计算最后一行。否则,CRLF字符的数量将被高估。我还假设只有一个CRLF对,如果该行是72个字符。这包括最后一行,但如果它不超过72个字符则不包括。
newline_size = ((code_padded_size) / 72) * 2
所以把它们放在一起:
unsigned int code_padded_size = ((input_size + ( (input_size % 3) ? (3 - (input_size % 3)) : 0) ) / 3) * 4;
unsigned int newline_size = ((code_padded_size) / 72) * 2;
unsigned int total_size = code_padded_size + newline_size;
或者让它更具可读性:
unsigned int adjustment = ( (input_size % 3) ? (3 - (input_size % 3)) : 0);
unsigned int code_padded_size = ( (input_size + adjustment) / 3) * 4;
unsigned int newline_size = ((code_padded_size) / 72) * 2;
unsigned int total_size = code_padded_size + newline_size;
答案 2 :(得分:6)
这是一个简单的C实现(没有模数和三元运算符),用于原始base64编码的大小(标准'='填充):
int output_size;
output_size = ((input_size - 1) / 3) * 4 + 4;
为此,如果需要,您需要为CRLF添加任何额外开销。标准base64编码(RFC 3548或RFC 4648)允许CRLF换行符(64或76个字符),但不需要它。 MIME变体(RFC 2045)在每76个字符后需要换行符。
例如,使用上面构建的76个字符行的总编码长度:
int final_size;
final_size = output_size + (output_size / 76) * 2;
有关更多变体,请参阅base64 wikipedia entry。
答案 3 :(得分:3)
查看b64 library。如果传递NULL
,函数b64_encode2()可以给出所需大小的最大估计值,这样你就可以确定地分配内存,然后再次调用传递缓冲区并让它进行转换。
答案 4 :(得分:3)
我在python中遇到了类似的情况,使用codecs.iterencode(text,“base64”)正确的计算是:
adjustment = 3 - (input_size % 3) if (input_size % 3) else 0
code_padded_size = ( (input_size + adjustment) / 3) * 4
newline_size = ((code_padded_size) / 76) * 1
return code_padded_size + newline_size
答案 5 :(得分:2)
Base 64将3个字节转换为4个。
如果您设置的位不是24位的倍数,则必须将其填充以使其具有24位(3字节)的倍数。
答案 6 :(得分:2)
我认为这个公式应该有效:
b64len = (size * 8 + 5) / 6
答案 7 :(得分:1)
if (inputSize == 0) return 0;
int size = ((inputSize - 1) / 3) * 4 + 4;
int nlines = (size - 1)/ maxLine + 1;
return size + nlines * 2;
当且仅当最后一行不完全符合最大行长度时,此公式才会添加终止CRLF
(MIME,rfc2045)。
答案 8 :(得分:0)
MIME兼容的base64编码二进制数据的实际长度通常约为原始数据长度的137%,但对于非常短的消息,由于头文件的开销,开销可能会高很多。非常粗略地说,base64编码的二进制数据的最终大小等于原始数据大小的1.37倍+ 814字节(对于标题)。
换句话说,您可以使用以下公式估算解码数据的大小:
BytesNeededForEncoding = (string_length(base_string) * 1.37) + 814;
BytesNeededForDecoding = (string_length(encoded_string) - 814) / 1.37;