如何从文件中读取二进制格式的字符串?
How to read a binary formatted string from a file?
我想以一种无法(轻松)读取的方式将字符串存储在文件中。所以我使用这样的 BinaryFormatter:
using (FileStream fs = File.Create(sfDialog.FileName, 2048, FileOptions.None))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, Encoding.Unicode.GetBytes(this.BodyText));
}
其中 this.BodyText
是要保存的字符串。
现在我正在努力从文件中读回它。我尝试 BinaryReader
没有成功,所以我想,我必须使用 BinaryFormatter
。我尝试了 Deserialize
方法,但它 returns 是一个无法转换为字符串的对象。此外 Convert.ToBase64String
不能用于对象。
有谁知道如何解决我的问题?
使用此函数进行加密和解密。
string passPhrase = "Pasword"; // can be any string
string saltValue = "sALtValue"; // can be any string
string hashAlgorithm = "SHA1"; // can be "MD5"
int passwordIterations = 7; // can be any number
string initVector = "~1B2c3D4e5F6g7H8"; // must be 16 bytes
int keySize = 256; // can be 192 or 128
private string Encrypt(string data)
{
byte[] bytes = Encoding.ASCII.GetBytes(this.initVector);
byte[] rgbSalt = Encoding.ASCII.GetBytes(this.saltValue);
byte[] buffer = Encoding.UTF8.GetBytes(data);
byte[] rgbKey = new PasswordDeriveBytes(this.passPhrase, rgbSalt, this.hashAlgorithm, this.passwordIterations).GetBytes(this.keySize / 8);
RijndaelManaged managed = new RijndaelManaged();
managed.Mode = CipherMode.CBC;
ICryptoTransform transform = managed.CreateEncryptor(rgbKey, bytes);
MemoryStream stream = new MemoryStream();
CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write);
stream2.Write(buffer, 0, buffer.Length);
stream2.FlushFinalBlock();
byte[] inArray = stream.ToArray();
stream.Close();
stream2.Close();
return Convert.ToBase64String(inArray);
}
private string Decrypt(string data)
{
byte[] bytes = Encoding.ASCII.GetBytes(this.initVector);
byte[] rgbSalt = Encoding.ASCII.GetBytes(this.saltValue);
byte[] buffer = Convert.FromBase64String(data);
byte[] rgbKey = new PasswordDeriveBytes(this.passPhrase, rgbSalt, this.hashAlgorithm, this.passwordIterations).GetBytes(this.keySize / 8);
RijndaelManaged managed = new RijndaelManaged();
managed.Mode = CipherMode.CBC;
ICryptoTransform transform = managed.CreateDecryptor(rgbKey, bytes);
MemoryStream stream = new MemoryStream(buffer);
CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Read);
byte[] buffer5 = new byte[buffer.Length];
int count = stream2.Read(buffer5, 0, buffer5.Length);
stream.Close();
stream2.Close();
return Encoding.UTF8.GetString(buffer5, 0, count);
}
我同意其他人的意见,你应该使用一些适当的加密而不是这个。
但要回答您的实际问题:
您正在序列化一个字节数组。这就是反序列化时得到的结果。
因此,反序列化后,转换为 byte[]
并将此字节数组转换为字符串:
var s = Encoding.Unicode.GetString((byte[])deserializedValue);
如果您希望字符串不容易被读取,您应该使用适当的加密。
例如,您可以使用 DPAPI,它将使用您的 windows 凭据作为加密的密钥。 (more details about the pros/cons of that concept here)
或者您可以 read Josh Galloway's article 探索 3 种不同的方法,其中第三种看起来很有希望,即使我自己没有尝试过,但最酷的部分是它不需要您的加密数据在 .config 文件中。)
还有,关于原来的问题,别忘了既然你打过电话
Encoding.Unicode.GetBytes(this.BodyText)
反序列化时,您需要调用 Encoding
服务从字节数组中获取 Unicode 字符串:
Encoding.Unicode.GetString(myByteArray);
试试这个:
using (FileStream fs = File.Create(sfDialog.FileName, 2048, FileOptions.None))
{
BinaryFormatter deserializer = new BinaryFormatter();
deserializedObject = System.Text.Encoding.Unicode.GetString((byte[])deserializer.Deserialize(memoryStream));
}
我想以一种无法(轻松)读取的方式将字符串存储在文件中。所以我使用这样的 BinaryFormatter:
using (FileStream fs = File.Create(sfDialog.FileName, 2048, FileOptions.None))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, Encoding.Unicode.GetBytes(this.BodyText));
}
其中 this.BodyText
是要保存的字符串。
现在我正在努力从文件中读回它。我尝试 BinaryReader
没有成功,所以我想,我必须使用 BinaryFormatter
。我尝试了 Deserialize
方法,但它 returns 是一个无法转换为字符串的对象。此外 Convert.ToBase64String
不能用于对象。
有谁知道如何解决我的问题?
使用此函数进行加密和解密。
string passPhrase = "Pasword"; // can be any string
string saltValue = "sALtValue"; // can be any string
string hashAlgorithm = "SHA1"; // can be "MD5"
int passwordIterations = 7; // can be any number
string initVector = "~1B2c3D4e5F6g7H8"; // must be 16 bytes
int keySize = 256; // can be 192 or 128
private string Encrypt(string data)
{
byte[] bytes = Encoding.ASCII.GetBytes(this.initVector);
byte[] rgbSalt = Encoding.ASCII.GetBytes(this.saltValue);
byte[] buffer = Encoding.UTF8.GetBytes(data);
byte[] rgbKey = new PasswordDeriveBytes(this.passPhrase, rgbSalt, this.hashAlgorithm, this.passwordIterations).GetBytes(this.keySize / 8);
RijndaelManaged managed = new RijndaelManaged();
managed.Mode = CipherMode.CBC;
ICryptoTransform transform = managed.CreateEncryptor(rgbKey, bytes);
MemoryStream stream = new MemoryStream();
CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write);
stream2.Write(buffer, 0, buffer.Length);
stream2.FlushFinalBlock();
byte[] inArray = stream.ToArray();
stream.Close();
stream2.Close();
return Convert.ToBase64String(inArray);
}
private string Decrypt(string data)
{
byte[] bytes = Encoding.ASCII.GetBytes(this.initVector);
byte[] rgbSalt = Encoding.ASCII.GetBytes(this.saltValue);
byte[] buffer = Convert.FromBase64String(data);
byte[] rgbKey = new PasswordDeriveBytes(this.passPhrase, rgbSalt, this.hashAlgorithm, this.passwordIterations).GetBytes(this.keySize / 8);
RijndaelManaged managed = new RijndaelManaged();
managed.Mode = CipherMode.CBC;
ICryptoTransform transform = managed.CreateDecryptor(rgbKey, bytes);
MemoryStream stream = new MemoryStream(buffer);
CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Read);
byte[] buffer5 = new byte[buffer.Length];
int count = stream2.Read(buffer5, 0, buffer5.Length);
stream.Close();
stream2.Close();
return Encoding.UTF8.GetString(buffer5, 0, count);
}
我同意其他人的意见,你应该使用一些适当的加密而不是这个。
但要回答您的实际问题: 您正在序列化一个字节数组。这就是反序列化时得到的结果。
因此,反序列化后,转换为 byte[]
并将此字节数组转换为字符串:
var s = Encoding.Unicode.GetString((byte[])deserializedValue);
如果您希望字符串不容易被读取,您应该使用适当的加密。
例如,您可以使用 DPAPI,它将使用您的 windows 凭据作为加密的密钥。 (more details about the pros/cons of that concept here)
或者您可以 read Josh Galloway's article 探索 3 种不同的方法,其中第三种看起来很有希望,即使我自己没有尝试过,但最酷的部分是它不需要您的加密数据在 .config 文件中。)
还有,关于原来的问题,别忘了既然你打过电话
Encoding.Unicode.GetBytes(this.BodyText)
反序列化时,您需要调用 Encoding
服务从字节数组中获取 Unicode 字符串:
Encoding.Unicode.GetString(myByteArray);
试试这个:
using (FileStream fs = File.Create(sfDialog.FileName, 2048, FileOptions.None))
{
BinaryFormatter deserializer = new BinaryFormatter();
deserializedObject = System.Text.Encoding.Unicode.GetString((byte[])deserializer.Deserialize(memoryStream));
}