我正在编写一个配置单元UDF以将EBCDIC字符转换为十六进制。 蜂巢表中存在急转字符。目前,我可以将其转换,但是转换时它忽略了几个字符。
示例:
这是存储在表中的EBCDIC值:
AGNSAñA¦Ã»ÃÃõµjÂqÂÂÃ()
转换后的十六进制:
c1c7d5e2000a5cd4f6ef99187d07067203a0200258dd9736009f000000800017112400000000001000084008403c000000000000000080
我想要作为输出:
c1c7d5e200010a5cd4f6ef99187d0706720103a0200258dd9736009f000000800017112400000000001000084008403c000000000000000080
忽略转换以下EBCDIC字符:
01-是标题的开始
10-逃脱
15-换行。
以下是我到目前为止尝试过的代码:
public class EbcdicToHex extends UDF {
public String evaluate(String edata) throws UnsupportedEncodingException {
byte[] ebcdiResult = getEBCDICRawData(edata);
String hexResult = getHexData(ebcdiResult);
return hexResult;
}
public byte[] getEBCDICRawData (String edata) throws UnsupportedEncodingException {
byte[] result = null;
String ebcdic_encoding = "IBM-037";
result = edata.getBytes(ebcdic_encoding);
return result;
}
public String getHexData(byte[] result){
String output = asHex(result);
return output;
}
public static String asHex(byte[] buf) {
char[] HEX_CHARS = "0123456789abcdef".toCharArray();
char[] chars = new char[2 * buf.length];
for (int i = 0; i < buf.length; ++i) {
chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
}
return new String(chars);
}
}
在转换时,它忽略了几个EBCDIC字符。如何使它们也转换为十六进制?
答案 0 :(得分:1)
我认为问题出在其他地方,我创建了一个小测试用例,在其中我根据您声称将被忽略的3个字节创建了一个String,但在我的输出中,它们似乎正确转换了:
private void run(String[] args) throws Exception {
byte[] bytes = new byte[] {0x01, 0x10, 0x15};
String str = new String(bytes, "IBM-037");
byte[] result = getEBCDICRawData(str);
for(byte b : result) {
System.out.print(Integer.toString(( b & 0xff ) + 0x100, 16).substring(1) + " ");
}
System.out.println();
System.out.println(evaluate(str));
}
输出:
01 10 15
011015
基于此,看来您的getEBCDICRawData
和evaluate
方法似乎都可以正常工作,并让我相信您的String值开始时可能已经不正确。可能是String已经缺少这些字符了吗?还是远射,但字符集不正确?有不同的EBCDIC字符集,所以也许String是使用不同的字符集组成的?尽管我怀疑这对于01、10和15个字节会产生很大的不同。
最后一点,但可能与您的问题无关,我通常更喜欢在charset对象上使用编码/解码函数进行此类转换:
String charset = "IBM-037";
Charset cs = Charset.forName(charset);
ByteBuffer bb = cs.encode(str);
CharBuffer cb = cs.decode(bb);