在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);
返回<!>“; System.Text.UTF8Encoding <!>”;
解决方案
尝试Encoding
类上的静态函数,它为您提供各种编码的实例。您不需要实例化==
只是为了转换为/从字节数组。你是如何比较代码中的字符串的?
修改强>
您正在比较数组,而不是字符串。它们是不平等的,因为它们指的是两个不同的阵列;使用<=>运算符只会比较它们的引用,而不是它们的值。您需要检查数组的每个元素,以确定它们是否相同。
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位字符,然后再返回,而不会丢失任何信息。
在上面描述的特定情况下,使用二进制文件,您将无法<!>“混淆标题<!>中的元数据。并且让事情正常工作,除非你搞乱的数据长度不变。例如,如果标题包含
{any}{any}ABC{any}{any}
并且您想要将ABC更改为DEF,这应该可以按照您的意愿使用。但是如果你想将ABC改为WXYZ,你必须写下<!>“C <!>”之后的字节。或者你(实质上)将所有内容向右移动一个字节。在典型的二进制文件中,这会使事情变得非常糟糕。
如果<!>之后的字节“ABC <!>”;是空格或空字符,写更大的替换数据更有可能不会造成麻烦 - 但你仍然不能只用.NET字符串中的WXYZ替换ABC,使其更长 - 你必须替换ABC {whatever_follows_it}与WXYZ。鉴于此,您可能会发现将数据保留为字节并将替换数据一次写入一个字节会更容易。
由于.NET字符串使用Unicode字符串这一事实,您不能再像C语言中那样执行此操作。在大多数情况下,您甚至不应该尝试来自字符串&lt; ; - &gt;字节数组,除非内容实际上是 text 。
我必须明确这一点:在.NET中,如果 byte []
数据不是 text ,那么请勿尝试将其转换为字符串
,除了特殊的 Base64 编码文本通道上的二进制数据。这是在.NET中工作的人们普遍存在的误解。
您的问题似乎是您比较字节数组的方式:
Response.Write((fileData == recapturedBytes));
这将始终返回false,因为您要比较字节数组的地址,而不是它包含的值。比较字符串数据,或使用比较字节数组的方法。您也可以这样做:
Response.Write(Convert.ToBase64String(fileData) == Convert.ToBase64String(recapturedBytes));