バイト配列を文字列に変換し、C#で再び戻す
質問
だからここに契約がある:私はファイルを(バイトから)開き、文字列に変換してヘッダーのメタデータを混乱させ、バイトに戻し、保存しようとしています。私が今直面している問題は、このコードにあります。前後に変換された(ただし変更されていない)文字列を元のバイト配列と比較すると、等しくありません。どうすればこれを機能させることができますか?
public static byte[] StringToByteArray(string str)
{
UTF8Encoding encoding = new UTF8Encoding();
return encoding.GetBytes(str);
}
public string ByteArrayToString(byte[] input)
{
UTF8Encoding enc = new UTF8Encoding();
string str = enc.GetString(input);
return str;
}
これらを比較する方法は次のとおりです。
byte[] fileData = GetBinaryData(filesindir[0], Convert.ToInt32(fi.Length));
string fileDataString = ByteArrayToString(fileData);
byte[] recapturedBytes = StringToByteArray(fileDataString);
Response.Write((fileData == recapturedBytes));
UTF-8であると確信しています:
StreamReader sr = new StreamReader(filesindir[0]);
Response.Write(sr.CurrentEncoding);
<!> quot; System.Text.UTF8Encoding <!> quot;を返す。
解決
さまざまなエンコーディングのインスタンスを提供するEncoding
クラスの静的関数を試してください。バイト配列との間で変換するためだけに==
をインスタンス化する必要はありません。コード内の文字列をどのように比較していますか?
編集
文字列ではなく配列を比較しています。 2つの異なる配列を参照するため、これらは等しくありません。 <=>演算子を使用すると、値ではなく参照のみが比較されます。配列の各要素を調べて、それらが同等であるかどうかを判断する必要があります。
public bool CompareByteArrays(byte[] lValue, byte[] rValue)
{
if(lValue == rValue) return true; // referentially equal
if(lValue == null || rValue == null) return false; // one is null, the other is not
if(lValue.Length != rValue.Length) return false; // different lengths
for(int i = 0; i < lValue.Length; i++)
{
if(lValue[i] != rValue[i]) return false;
}
return true;
}
他のヒント
生のバイト(8ビットの場合は印刷できない文字)があり、それらを.NET文字列として操作し、バイトに戻す場合は、次を使用して行うことができます
Encoding.GetEncoding(1252)
UTF8Encodingの代わり。このエンコードは、8ビット値を取り、.NET 16ビット文字に変換し、情報を失うことなく元に戻すように機能します。
上記で説明した特定のケースでは、バイナリファイルを使用して、<!> quot;ヘッダーのメタデータを混乱させることはできません<!> quot;混乱させるデータの長さが変わらない限り、正しく動作するようにします。たとえば、ヘッダーに次が含まれている場合
{any}{any}ABC{any}{any}
ABCをDEFに変更したい場合は、希望どおりに機能するはずです。ただし、ABCをWXYZに変更する場合は、<!> quot; C <!> quot;に続くバイトを上書きする必要があります。または、(本質的に)すべてを1バイトさらに右に移動します。典型的なバイナリファイルでは、これは物事を大きく混乱させます。
<!> quot; ABC <!> quotの後のバイトスペースまたはヌル文字である場合、より大きな置換データを書き込んでも問題が発生しない可能性が高くなります-しかし、.NET文字列内のABCをWXYZに置き換えるだけで長くすることはできません-ABC {whatever_follows_it}を置き換える必要がありますWXYZで。そのため、データをバイトのままにして、一度に1バイトずつ置換データを書き込む方が簡単な場合があります。
。 <!> lt;-<!> gt;コンテンツが実際に text でない限り、バイト配列。
この点を明確にする必要があります。 .NETでは、byte[]
データがテキストでない場合、string
に変換しようとしないでください。 >テキストチャネルを介したバイナリデータの特別な Base64 エンコードを除きます。これは、.NETで働く人々の間で広く受け入れられている誤解です。
あなたの問題は、バイトの配列を比較する方法のように見えます:
Response.Write((fileData == recapturedBytes));
これは、バイト配列に含まれる値ではなく、バイト配列のアドレスを比較しているため、常にfalseを返します。文字列データを比較するか、バイト配列を比較する方法を使用します。代わりにこれを行うこともできます:
Response.Write(Convert.ToBase64String(fileData) == Convert.ToBase64String(recapturedBytes));