web-dev-qa-db-ja.com

無効な文字エラーをスローするBase64文字列

必要ないのに、Base64の無効な文字エラーが発生し続けます。

プログラムはXMLファイルを受け取り、それをドキュメントにエクスポートします。ユーザーが希望する場合は、ファイルも圧縮します。圧縮は正常に機能し、UTF-8にエンコードされてファイルに書き込まれるBase64文字列を返します。

ドキュメントをプログラムに再読み込みするとき、圧縮されているかどうかを確認する必要がある場合、コードは次のとおりです。

byte[] gzBuffer = System.Convert.FromBase64String(text);
return "1F-8B-08" == BitConverter.ToString(new List<Byte>(gzBuffer).GetRange(4, 3).ToArray());

文字列の先頭をチェックして、GZipsコードが含まれているかどうかを確認します。

さて、問題はすべてのテストが機能することです。文字列を取得して圧縮し、解凍して、元の文字列と比較します。問題は、ADO Recordsetから返された文字列を取得するときです。文字列は、ファイルに書き込まれたものとまったく同じです(最後に「\ 0」が追加されていますが、文字列全体をテストメソッドにコピーして貼り付け、それを圧縮/解凍することさえできます。問題なく動作します。

テストはパスしますが、コードはまったく同じ文字列を使用して失敗しますか?唯一の違いは、通常の文字列を宣言して渡すだけではなく、レコードセットから返される文字列を取得することです。

私が間違っていることについてのアイデアはありますか?

14
Brandon

あなたは言う

文字列は、ファイルに書き込まれたものとまったく同じです(最後に「\ 0」が追加されていますが、それでも何もしないと思います)。

_Convert.FromBase64String_ は "\ 0"を考慮しないため、実際には何かをします(コードがFormatException: "Base-64 stringに無効な文字をスローします")。有効なBase64文字である。

_  byte[] data1 = Convert.FromBase64String("AAAA\0"); // Throws exception
  byte[] data2 = Convert.FromBase64String("AAAA");   // Works
_

解決策:ゼロ終端を取り除きます。(多分.Trim("\0")を呼び出します)

メモ

_Convert.FromBase64String_ のMSDNドキュメントは、次の場合にFormatExceptionをスローすると言っています

空白文字を無視して、sの長さがゼロまたは4の倍数ではありません。

-または-

Sの形式が無効です。 sには、base 64以外の文字、3つ以上の埋め込み文字、または埋め込み文字間の空白以外の文字が含まれています。

そしてそれ

ゼロから昇順の基数64桁は、大文字の「A」から「Z」、小文字の「a」から「z」、数字の「0」から「9」、および記号「+」と「/」です。 。

16

Null文字が許可されるかどうかは、実際には問題のbase64コーデックに依存します。 Base64標準の曖昧さ(信頼できる正確な仕様はありません)を考えると、多くの実装ではそれを空白として無視するだけです。そして、他の人はそれを問題としてフラグを立てることができます。そして、バグの多いものは気付かず、喜んでそれをデコードしようとします...:-/

しかし、c#の実装はそれを好まないようです(これは1つの有効なアプローチです)。

1つの小さな追加コメント:UTF-8は要件ではありません。ISO-8859-x、別名Latin-x、および7ビットAsciiも同様に機能します。これは、Base64が7ビットのASCII互換エンコーディングすべてで機能する7ビットのサブセットのみを使用するように特別に設計されているためです。

3
StaxMan

文字列の末尾から\ 0を削除できない場合は、エンコードする文字列ごとに独自の文字を追加し、デコード時にそれを削除できます。

0
abatishchev

文字列からBase64を変換する際の1つの問題は、一部の変換関数は前述の "data:image/jpg; base64"を使用し、他の関数は実際のデータのみを受け入れることです。

0
SteveCav
string stringToDecrypt = HttpContext.Current.Request.QueryString.ToString()

//文字列に変更stringToDecrypt = HttpUtility.UrlDecode(HttpContext.Current.Request.QueryString.ToString())

0
Uday