3

私はこの奇妙な問題に直面しています。私"Character.reverseBytes(char ch)"は暗号化の目的でこの方法を使用します。内部で実行すると、正常に動作しますNetBeans。しかし、私がそれを外で実行しようとすると、それは奇妙な出力を与えます。

問題は、2つの場合に、2つの異なるエンコード方法(またはそのようなもの)を使用することだと思います。次のコードは問題を示しています。

import java.io.File;
import java.io.PrintWriter;
import java.util.ArrayList;

public class Encryptor {

    public static String encode(String in) {
        ArrayList<Character> list = new ArrayList<Character>();
        for (int i = 0; i < in.length(); i++) {
            list.add(Character.reverseBytes(in.charAt(i)));
        }
        return arrayToString(list);
    }

    public static String decode(String in) {
        ArrayList<Character> list = new ArrayList<Character>();
        for (int i = 0; i < in.length(); i++) {
            list.add(Character.reverseBytes(in.charAt(i)));
        }
        return arrayToString(list);
    }

    private static String arrayToString(ArrayList<Character> list) {
        char[] ch = new char[list.size()];
        for (int i = 0; i < list.size(); i++) {
            ch[i] = list.get(i);
        }
        return String.copyValueOf(ch);
    }

    public static void main(String[] args) throws java.io.FileNotFoundException, java.io.IOException {
        String pass = "Password";
        String passEn = encode(pass);
        File file = new File(System.getProperty("user.dir") + "/pass.txt");
        file.createNewFile();
        PrintWriter pr = new PrintWriter(file);
        pr.write(passEn);
        pr.flush();
        passEn = new java.util.Scanner(file).next();
        String passDe = decode(passEn);
        String msg;
        msg = "Initial : " + pass
                + "\nEncrypted : " + passEn
                + "\nDecrypted : " + passDe;
        javax.swing.JOptionPane.showMessageDialog(null, msg);
    }
}

まず、暗号化された単語をファイルに保存し、次に保存された単語をデコードしてみます。これにより、上記の2つの場合に2つの異なる出力が得られます。

これを修正する方法はありますか?

4

1 に答える 1

7

基本的にCharacter.reverseBytes、やや恣意的な UTF-16 コード単位を提供しています。後で取得した文字が有効な文字列を形成するという保証はまったくありません。たとえば、「半分」のサロゲートペアや、Unicode で特定の意味を持たない文字が存在する可能性があります。

さらに重要なことに、「テキスト」をファイルに書き込んで読み返すと、特にエンコーディングを指定していないため、異なる値が得られる可能性があります。使用しているデフォルトのエンコーディングでは、最終的に使用した文字がサポートされない可能性が非常に高くなります。

基本的に、あなたはこれをしたくありません。文字列の暗号化は、基本的に次の形式を取る必要があります。

  • 文字列を固定エンコーディング (UTF-8 など) でバイトにエンコードします。
  • バイナリ データを暗号化します (自分で作成しないでください。Java には多くの暗号化機能が含まれています)。
  • 暗号化されたバイナリ データを必要な場所に渡します。バイナリ データを文字列として表す必要がある場合は、base64 などを使用して、後で正確なバイナリ データを復元できるようにします。

次に、復号化するには、各操作を逆にします。

  • 暗号化されたバイナリ データを取得します。これには、base64 からの変換が含まれる場合があります。
  • 以前に使用した暗号化アルゴリズムに基づいて、適切な復号化手順 (バイナリからバイナリへ) を実行します。
  • 最初に使用したのと同じエンコーディングを使用して、結果(まだバイト)を文字列に変換します

任意のバイナリ データをテキストとして扱うことCharacter.reverseBytesは、非常に大雑把な方法で実際に行っていることですが、非常に悪い考えです。

于 2012-10-02T06:20:19.600 に答える