1

文字列を UTF-8 から CP1047 に変換してから、16 進エンコードを実行していますが、これはうまく機能します。次に、16 進文字列をデコードし、UTF-8 形式でコンソールに表示することで、逆変換を行っています。問題は、エンコーディング メソッドに渡した適切な文字列を取得していないことです。以下は、私がコーディングしたコードです。

public class HexEncodeDecode {

    public static void main(String[] args) throws UnsupportedEncodingException,
            DecoderException {
        String reqMsg = "ISO0150000150800C220000080000000040000050000000215102190000000014041615141800001427690161 0B0    000123450041234";
        char[] hexed = getHex(reqMsg, "UTF-8", "Cp1047");

        System.out.println(hexed);

        System.out.println(getString(hexed));
    }

    public static char[] getHex(String source, String inputCharacterCoding,
            String outputCharacterCoding) throws UnsupportedEncodingException {
        return Hex.encodeHex(new String(source.getBytes(inputCharacterCoding),
                outputCharacterCoding).getBytes(), false);
    }

    public static String getString(char[] source) throws DecoderException,
            UnsupportedEncodingException {
        return new String(Hex.decodeHex(source), Charset.forName("UTF-8"));
    }
}

私が得ている出力は次のとおりです。

    C3B1C3AB7CC290C291C295C290C290C290C290C291C295C290C298C290C290C3A41616C290C290C290C290C290C298C290C290C290C290C290C290C290C290C294C290C290C290C290C290C295C290C290C290C290C290C290C29016C291C295C291C29016C291C299C290C290C290C290C290C290C290C290C291C294C290C294C291C296C291C295C291C294C291C298C290C290C290C290C291C2941604C296C299C290C291C296C291C280C290C3A2C290C280C280C280C280C290C290C290C29116C293C294C295C290C290C294C29116C293C294
ñë|äâ

そのため、入力文字列を印刷する際に助けが必要です。

予想される出力は次のようになります。

C3B1C3AB7CC290C291C295C290C290C290C290C291C295C290C298C290C290C3A41616C290C290C290C290C290C298C290C290C290C290C290C290C290C290C294C290C290C290C290C290C295C290C290C290C290C290C290C29016C291C295C291C29016C291C299C290C290C290C290C290C290C290C290C291C294C290C294C291C296C291C295C291C294C291C298C290C290C290C290C291C2941604C296C299C290C291C296C291C280C290C3A2C290C280C280C280C280C290C290C290C29116C293C294C295C290C290C294C29116C293C294
ISO0150000150800C220000080000000040000050000000215102190000000014041615141800001427690161 0B0    000123450041234
4

3 に答える 3

5
new String(source.getBytes(inputCharacterCoding), outputCharacterCoding)
    .getBytes()

これはおそらくあなたが思っていることをしません。

まず最初に: aStringには encoding がありません。後で繰り返します: a Stringhas no encoding

AStringは、文字を表すことを目的とした一連のトークンです。この目的のために、Java は一連のchars を使用します。彼らは伝書鳩でもありえます。

UTF8、CP1047 などは単なる文字コードです。次の 2 つの操作を実行できます。

  • エンコーディング: 伝書鳩 ( chars) のストリームをバイトのストリームに変換します。
  • デコーディング: バイトのストリームを伝書鳩 ( chars) のストリームに変換します。

基本的に、あなたの基本的な仮定は間違っています。エンコーディングを に関連付けることはできませんString。実際の入力は、別の文字セットを使用して再エンコードしたい特定のエンコーディング(あなたの場合はUTF-8)byteの結果であることがわかっているストリーム(多くの場合、バイト配列ではない)でなければなりません(あなたの場合、CP1047)。

ここでの本当の答えの「秘密」はあなたのHex.encodeHex()メソッドのコードですが、あなたはそれを示していないので、これは私が集めることができるのと同じくらい良い答えです.

于 2015-04-16T13:14:55.157 に答える
1

reqMsgエンコーディングがなくなったので、UTF-8 から "Cp1047" に変換しようとしても無意味です (そして損害を与えます)。

reqMsgが将来、ディスクやネットワークなどの外部ソースから送信される場合は、デコードする必要があります。おそらく、これが混乱の原因です。おそらくあなたはやっているでしょう: UTF-8->Unicode(String)->CP1047->HEX. stdout に書き込むと、HEX は ASCII エンコードされる可能性があります。

次の例では、CP1047 (Unicode->CP1047->HEX) に変換した後、元の文字列に基づいて ASCII 16 進文字列を作成します。

    String reqMsg = "ISO0150000150800C220000080000000040000050000000215102190000000014041615141800001427690161 0B0    000123450041234";

    // encode to cp1047 represented as Hex
    byte[] reqMsqBytes = reqMsg.getBytes("Cp1047");
    char[] hex = Hex.encodeHex(reqMsqBytes);   
    System.out.println(hex);

    // decode
    String respMsqBytes = new String(Hex.decodeHex(hex), "Cp1047");
    System.out.println(respMsqBytes);
于 2015-04-16T14:06:14.883 に答える