2011-01-20 18 views
1

在Java的字节序列,是有图书馆的任何地方,将给出一个字节序列(最好表现为十六进制),转化为给定的InputStream另一个字节序列?例如:翻译给出的InputStream

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 C3 BE AB 00 23 C3 BE AB 00 

转换后,其结果将是

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

并不清楚你的要求。什么是“翻译成另一个字节序列”呢? “MyMagicLibrary”上的``translate'方法究竟应该做什么? – 2011-01-20 15:35:08

+0

所以你想要一个文件并用一些其他的字节序列替换所有出现的字节序列。我不认为有一个图书馆可以这样做,但编写自己的图书并不难。 – 2011-01-20 15:58:06

回答

2

一旦我做了这样的事情(为平凡的补丁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

如果妳意味着ü要使用一类界河从十六进制转换,以及这里诅咒 的两种方法我usualluy使用,美国可以把它们放在一个类内部和重用任何其中u希望

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。

否则它逐字节将最有可能是非常低效的,但是容易测试。一旦你得到了你想要的结果,你可以通过读取和解析整个缓冲区并一次性吐出多个结果字节来进行调整,每行格式化可能需要16“字节”字符。这一点完全取决于你。

0

实现此目的的一种方法是使用IOUtils和String替换方法。

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"); 
}