2011-01-20 5 views
1

Javaでは、バイトシーケンス(16進数で表現されている)を指定すると、InputStreamが指定された別のバイトシーケンスに変換されるライブラリがどこにありますか?例えば:翻訳後の入力ファイル(16進数でのように見えた)InputStreamを指定してバイトシーケンスを変換する

00 00 12 18 33 C3 BE AB 00 23 C3 BE AB 00 

場合uはuが使用することを意味している場合

InputStream input = new FileInputStream(new File(...)); 
OutputStream output = new FileOutputStream(new File(...)); 
String fromHex = "C3BEAB"; 
String toHex = "EAF6" 
MyMagicLibrary.translate(fromHex, toHex, input, output) 

ので、結果は

00 00 12 18 33 EA F6 00 23 EA F6 00 
+2

あなたが何を求めているのかはっきりしません。 「別のバイトシーケンスに変換する」とはどういう意味ですか? 'MyMagicLibrary'の' translate'メソッドは何をすべきでしょうか? –

+0

ファイルを取得し、一連のバイトのすべての出現を他のバイトのシーケンスで置き換えたいとします。私はそれを行うための図書館はないと思うが、あなた自身で書くことは非常に難しいことではない。 –

答えて

2

いったん私はregexesを使って(exeファイルを簡単にパッチするための)このようなことをやりました。入力全体をbyte[]に読み込み、latin1を使用してStringに変換した後、置換を行い、元に戻しました。それは効率的ではありませんでしたが、それは全く問題ではありませんでした。正規表現は必要ありません。単純なString.replaceが行います。

しかし、あなたの場合には、それは非常に簡単かつ非常に効率的に行うことができます。

int count = 0; 
while (true) { 
    int n = input.read(); 
    if (n == (fromAsByteArray[count] & 255)) { 
     ++count; 
     if (count==fromAsByteArray.length) { // match found 
      output.write(toAsByteArray); 
      count = 0; 
     } 
    } else { // mismatch 
     output.write(fromAsByteArray, 0, count); // flush matching chars so far 
     count = 0; 
     if (n == -1) break; 
     output.write(n); 
     } 
    } 
} 
+0

私はこれに似たものを持っていましたが、あなたのアルゴリズムは私のものよりもきれいです。 – bajafresh4life

0

だろうクラスは16進数から16進数に変換します ここでは2つの方法を使用しています。クラス内に入れて再利用しても構いません。

public static String toHex(byte buf[]) { 
    StringBuffer strbuf = new StringBuffer(buf.length * 2); 
    int i; 

    for (i = 0; i < buf.length; i++) { 
     if (((int) buf[i] & 0xff) < 0x10) { 
      strbuf.append("0"); 
     } 

     strbuf.append(Long.toString((int) buf[i] & 0xff, 16)); 
    } 

    return strbuf.toString(); 
} 

public static byte[] fromHexString(String s) { 
    int len = s.length(); 
    byte[] data = new byte[len/2]; 
    for (int i = 0; i < len; i += 2) { 
     data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 
       + Character.digit(s.charAt(i + 1), 16)); 
    } 
    return data; 
} 

実際にコード内の各行はわかりませんが、通常は再利用します。

0

あなたの入力がスペースを持つことができるので、あなたが最初のスペースを削除するために、あなたの入力をスクラブする必要があります。文字のペアを読み終えたら、Byte.parseByte(twoCharString、16)を使い、String.formatを使ってStringに変換し直してください。

バイト単位で処理すると、テストするのは簡単ですが、非常に効率が悪い可能性があります。必要な結果が得られれば、バッファ全体を読み込んで解析し、複数の結果バイトを一度に吐き出すことで、それを微調整することができます。その時点であなた次第です。

0

これを実装する1つの方法は、IOUtilsとString replaceメソッドを使用することです。

public static void translate(byte[] fromHex, byte[] toHex, InputStream input, OutputStream output) throws IOException { 
    IOUtils.write(translate(fromHex, toHex, IOUtils.toByteArray(input)), output); 
} 

public static byte[] translate(byte[] fromHex, byte[] toHex, byte[] inBytes) throws UnsupportedEncodingException { 
    String inputText = new String(inBytes, "ISO-8859-1"); 
    String outputText = inputText.replace(new String(fromHex, "ISO-8859-1"), new String(toHex, "ISO-8859-1")); 
    return outputText.getBytes("ISO-8859-1"); 
} 
関連する問題