计算Base 64编码消息的大小

时间:2009-10-07 17:39:49

标签: c base64

我有一个二进制字符串,我在Base 64中编码。现在,我需要事先了解最终Base 64编码字符串的大小。

有没有办法计算出来?

类似的东西:

BinaryStringSize是64Kb 编码后,EncodedBinaryStringSize将为127Kb。

哦,代码在C中。

感谢。

9 个答案:

答案 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;

来源:http://en.wikipedia.org/wiki/Base64