私はBase 64でエンコードしているバイナリ文字列を持っています。ここで、Base 64でエンコードされた最終的な文字列のサイズを事前に知る必要があります。
それを計算する方法はありますか?
何かのようなもの:
BinaryStringSizeは64Kbです。EncodedBinaryStringSizeはエンコード後に127Kbになります。
ああ、コードはCです。
ありがとう。
Base64 (exactlyright を実行し、_=
_文字で末尾を埋め込んで、それを壊した場合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
_- byteで終了することもできるので、そこに余分なバイトがあり、コードを書くときにすべてのコードの最後で長さをチェックすることをお勧めします。 malloc()
に渡すものを探すだけでも、コーディングを簡単にするために、実際には数バイトを無駄にするバージョンを好むかもしれません。
_output_size = ((input_size * 4) / 3) + (input_size / 96) + 6;
_
geocarの答えは近いものでしたが、時々少しずれている可能性があります。
入力の3バイトごとに4バイトの出力があります。入力サイズが3の倍数でない場合は、1にするために追加する必要があります。それ以外の場合はそのままにしておきます。
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
コメントで述べたように、最後の行を適切に説明するには、合計サイズを2倍にする前に行幅で割る必要があります。そうしないと、CRLF文字の数が過大評価されます。また、行が72文字の場合、CRLFペアのみが存在すると想定しています。これには最後の行が含まれますが、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;
以下は、base64でエンコードされた未加工サイズ(標準の「=」パディング付き)の単純なC実装(モジュラス演算子および3項演算子なし)です。
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 を参照してください。
私は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
b64ライブラリ を確認してください。関数 b64_encode2() は、NULL
を渡した場合に必要なサイズの最大推定値を提供できるため、確実にメモリを割り当ててから、バッファを渡して再度呼び出し、それを実行させることができます。変換。
私はこの式がうまくいくと思います:
b64len = (size * 8 + 5) / 6
Base 64は3バイトを4に変換します。
ビットのセットが24ビットの倍数にならない場合は、24ビットの倍数(3バイト)になるようにパディングする必要があります。
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)を追加します。
MIME準拠のbase64でエンコードされたバイナリデータの実際の長さは通常、元のデータ長の約137%ですが、非常に短いメッセージの場合、ヘッダーのオーバーヘッドのためにオーバーヘッドが大幅に高くなる可能性があります。非常に大まかに言えば、base64でエンコードされたバイナリデータの最終的なサイズは、元のデータサイズの1.37倍+ 814バイト(ヘッダー用)です。
つまり、次の式を使用して、デコードされたデータのサイズを概算できます。
BytesNeededForEncoding = (string_length(base_string) * 1.37) + 814;
BytesNeededForDecoding = (string_length(encoded_string) - 814) / 1.37;