0

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() が何をするか、文字を追加し、それらを移動することを上で説明しました...なぜこれが起こっているのか誰にも分かりますか?

4

1 に答える 1

5

この例外の理由は、文字交換関数が無効なサロゲートペアを持つUTF-16文字列を生成することになるためです。とはいえ、コード[DC00-DFFF]の文字の前にコード[D800-DBFF]の文字がない文字が少なくとも1つあります。ターゲットエンコーディングで無効な文字を表す方法がないため、この文字列をファイルに書き込むことはできません。

より簡単な例でこの問題を示すために、同じ状況をシミュレートするコードを次に示します。

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など)を使用してください:)
于 2012-04-30T01:14:16.423 に答える