编码器回退写入文件时异常
本文关键字:异常 文件 回退 编码器 | 更新日期: 2023-09-27 18:32:34
我正在从MS Office Word 2010文件(.docx)中读取,然后弄乱它,然后将其写入一个新文件。我添加的唯一字符是大多数键盘上的字符(字母,数字,标点符号......),并且我还稍微移动了现有字符。
StreamReader sr = new StreamReader(File.OpenRead("fs.docx"));
string foo = sr.ReadToEnd();
sr.Close();
string foo2 = EncryptFile(foo);
StreamWriter sw = new StreamWriter(File.Create("sal.docx"));
sw.Write(foo2); // THIS IS WHERE THE EXCEPTION HAPPENS
sw.Close();
foo = DecryptFile(foo2);
StreamWriter sww = new StreamWriter(File.Create("sal2.docx"));
sww.Write(foo);
sww.Close();
public static string Salt(string Input)
{
Random rand = new Random();
string Output = "";
string BigSalt = "";
int SaltIncrement = rand.Next(4, 8);
for (int i = 0; i < 10; i++) {
BigSalt += FindCipherPlainText.Substring(rand.Next(0, FindCipherPlainText.Length), 1);
}
Input = BigSalt + Input;
for (int i = Input.Length; i >= 0; i--) {
if ((decimal)i % SaltIncrement == 0) {
Input = Input.Insert(i, FindCipherPlainText.Substring(rand.Next(0, FindCipherPlainText.Length), 1));
}
}
Input += FindCipherPlainText.Substring(rand.Next(0, FindCipherPlainText.Length), 1);
Input = ((SaltIncrement + 2) * 8).ToString().Substring(1, 1) + Input + ((SaltIncrement + 2) * 8).ToString().Substring(0, 1) + rand.Next(0, 10).ToString();
return Input;
}
public static string Mix(string Input) {
string Output = "";
if (Input.Length > 1)
{
if (Input.Length % 2 == 0)
{
Output = Input.Substring(Input.Length / 2);
Output += Input.Substring(0, Input.Length / 2);
}
else
{
Output = Input.Substring((Input.Length - 1) / 2);
Output += Input.Substring(0, (Input.Length - 1) / 2);
}
}
else {
return Input;
}
return Output;
}
public static string Shift(string Input) {
string Output = "";
bool Found = false;
for (int i = 0; i < Input.Length; i++) {
Found = false;
for (int ii = 0; ii < FindCipherPlainText.Length; ii++) {
if (Input.Substring(i, 1) == FindCipherPlainText.Substring(ii, 1)) {
Output = Output.Insert(0, ReplaceCipherPlainText.Substring(ii, 1));
Found = true;
break;
}
}
if (!Found) {
Output = Output.Insert(0, Input.Substring(i, 1));
}
}
return Output;
}
public static string EncryptFile(string Input) {
return Mix( Salt( Shift( Mix( Input))));
}
System.Text.EncoderFallbackException was unhandled
Message=Unable to translate Unicode character 'uDF23 at index 428 to specified code page.
Source=mscorlib
Index=428
这是我的代码,以及一些异常细节,我在上面描述了 EncryptFile() 和 DecryptFile() 的作用,添加字符,移动它们......有谁知道为什么会这样?
此异常的原因是字符交换函数最终生成具有无效代理项对的 UTF-16 字符串。也就是说,至少有一个代码为 [DC00-DFFF] 的字符前面没有代码为 [D800-DBFF] 的字符。此字符串无法写入文件,因为无法在目标编码中表示无效字符。
为了在更简单的示例中演示此问题,下面是一段模拟相同情况的代码:
static void Main(string[] args)
{
// A perfectly valid surrogate pair with 1st character in the D800-DBFF range,
// and 2nd character in the DC00-DFFF range.
string validSurrogate = "'uD801'uDC01";
// Creating an invalid surrogate pair just by swapping the two characters in the first string.
string invalidSurrogate = validSurrogate.Substring(1, 1) + validSurrogate[0];
// This will work fine.
File.WriteAllText("valid.txt", validSurrogate);
// --! But this will crash !--
File.WriteAllText("invalid.txt", invalidSurrogate);
}
我会推荐以下内容:
- 在所有加密/解密函数中使用字节数组而不是字符串。然后将这些字节数组直接写入文件,而不将它们视为文本。
- 如果这是一个"真实世界"的应用程序,而不是家庭作业或宠物项目,请使用加密标准(AES,3DES等)进行加密,而不是设计自己的密码:)