【问题标题】:java string with extended ascii codes to byte arrary (allocate one byte per code)具有扩展 ascii 代码的 java 字符串到字节数组(每个代码分配一个字节)
【发布时间】:2014-11-19 14:41:35
【问题描述】:

我有一个需要与 C 套接字客户端通信的 java nio 套接字服务器。 C 套接字客户端使用 127 以上的 ASCII 码向服务器发送数据,每个 ASCII 码使用一个字节。服务器需要发回相同的内容。

我需要将一个字符串转换成一个长度相同的字节数组(每个代码一个字节)。 该字符串类似于1200üö001001001,其中包含一些 127 以上的 ascii 代码。 在我所做的研究中,我没有找到解决方案。我试过这个

byte[] b = "1200üö001001001".getBytes("UTF-8");
byte[] b = "1200üö001001001".getBytes("US-ASCII");
byte[] b = "1200üö001001001".getBytes("ISO-8859-1");
byte[] b = "1200üö001001001".getBytes();

其中一些将 üö 转换为 ?? 或每个 ASCII 代码多个字节,导致字节数组和字符串之间的长度不同。

我需要一些帮助。

这是来自 C 套接字客户端的数据示例。点是来自客户端的 ascii 代码。

<code>
0000 00 ff 31 32 30 30 fc f6 00 01 08 e1 e0 00 00 00 ..1200..........
0010 00 00 14 00 00 00 31 36 34 36 30 30 32 38 30 30 ......1646002800
0020 30 30 30 30 30 34 31 38 30 31 32 30 30 30 30 30 0000041801200000
0030 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 0000001000000000
0040 30 30 31 30 30 30 30 30 30 30 30 30 30 30 31 30 0010000000000010
0050 30 30 36 31 30 30 30 30 30 30 36 31 30 30 30 30 0061000000610000
0060 30 30 35 31 35 39 31 31 31 34 30 39 32 33 31 33 0051591114092313
0070 32 31 31 32 33 32 30 35 31 34 30 39 32 33 30 36 2112320514092306
0080 39 39 39 39 39 39 30 30 30 30 30 35 35 31 35 39 9999990000055159
0090 31 31 33 32 39 38 20 20 20 20 33 38 38 33 33 38 113298    388338
00a0 38 33 20 20 20 20 20 20 20 42 41 43 20 50 41 4e 83       XXX PAN
00b0 41 4d 41 20 54 45 53 54 3e 48 4f 57 41 52 44 20 AMA TEST>HOWARD
00c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 50                P
00d0 41 30 32 33 30 30 31 30 30 31 31 30 30 32 30 30 A023001001100200
00e0 33 37 30 30 30 32 35 30 30 31 31 38 34 30 38 34 3700025001184084
00f0 30 38 34 30 30 30 30 39 31 31 30 30 30 30 30 30 0840000911000000
0100 31

This is the code i use to convert from hex string to byte array

line 4 i convert from binary eg. 1101 to equvalent hex string eg `3F`
line 13 i take the bitmap in hex string eg. `"fcf6000108e1e0000000000014000000"`
        that contains 32 chars and try to convert to 16 bytes, but this results in 20 bytes
        because some chars takes more than one byte


       1     // Set bitmaps
       2     if ( String.copyValueOf(zeros).indexOf("1", 64) == -1 ) { zeros[0] = '0'; }
       3     tmp = String.copyValueOf(zeros);
       4     bits = binToHex(tmp);
       5
       6     // check bits to send
       7     if ( zeros[0] == '0') {
       8             bits = bits.substring(0, 16);
       9     }
      10
      11      // join message
      12      tmp = sb.toString();
      13      trm = isoCode + hexToASCII(bits) + tmp.substring(39);
      14      System.out.println("Trama respuesta " + (new Timestamp((new Date()).getTime())).toString() + " " + trm);

// here the code to send back the message from nio socet to client
   line mark with 100 add 2 space because there is a header with a short value that have the length of
   the message to be readed by socket client

            byte[] bytes = message.getBytes("ISO-8859-1");
            writeLength = message.length();
            //writeLength = bytes.length;
       100  writeBuffer = ByteBuffer.allocate(writeLength + 2);
            writeBuffer.putShort( (short)writeLength );
            writeBuffer.put(message.getBytes());   // Para test
            //this.writeBuffer.putChar('\n');
            writeBuffer.flip();

//辅助方法

    public  String hexToASCII(String hex){

              if(hex.length()%2 != 0){

                 System.err.println("requires EVEN number of chars");
                 return null;
              }
              StringBuilder sb = new StringBuilder();
              //Convert Hex 0232343536AB into two characters stream.
              for( int i=0; i < hex.length()-1; i+=2 ){
                   /*
                    * Grab the hex in pairs
                    */
                  String output = hex.substring(i, (i + 2));
                  /*
                   * Convert Hex to Decimal
                   */
                  int decimal = Integer.parseInt(output, 16);
                  sb.append((char)decimal);
              }
              return sb.toString();
        }

private final String HEXES = "0123456789ABCDEF";
private final String HEX[] = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
private final String BIN[] = {"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};

  /*
   *  Convert binary to hex string
   */
      public String binToHex(String bin) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bin.length()-1 ; i += 4) {
            sb.append(HEX[ArrayUtils.indexOf(BIN, bin.substring(i, (i + 4)))]);
        } 
        return sb.toString();
    } 

【问题讨论】:

  • 我觉得你在发疯。上面的数据是二进制和 ASCII 混合的,除非你知道哪个是你沉没的。我不认为字节 0x15 之前的内容是字符数据。
  • Hot licks 这是一条 ISO 8583 1993 消息。前两个字节是一个短字节,其中包含后续消息的长度。接下来的 4 个字节是消息代码,接下来的 16 个字节是位图(在 ascii 代码中),其余的字节是消息。位图部分是我在以字节为单位进行转换时遇到的问题。
  • 啊,XY problem 的 Y 开始出现了。尝试询问“如何使用 Java NIO 套接字接收 ISO 8583:1993 消息?”并显示您开始使用的代码。

标签: java c++ c sockets


【解决方案1】:

您正在混合字节和字符。将 ü 和 ö 等字符编码为字节的方法有很多种,不同的编码每个字符占用不同的字节数。

请勿尝试将二进制流转换为字符串,除非您知道字节代表文本信息并且您首先知道使用哪种编码将文本转换为字节。如果数据不是文本字符串,请勿尝试将其解释为文本字符串,而只是希望每个字节都映射到合理的内容。

您可以直接使用字节数组或使用例如java.nio.ByteBuffer。如果数据中有文本字符串,可以单独将特定字节转换为字符串。

【讨论】:

    【解决方案2】:

    您的二进制位图受到字符编码转换的影响。那样做是没有意义的。您可以从十六进制转换为字节[]。

    这段代码给出了建议:

    String bitmapHex = "00112233445566778899aabbccddeeff"; 
    String isoCode = "1200";
    String data = "313030303030303031 and more";
    
    byte[] bitmap = javax.xml.bind.DatatypeConverter.parseHexBinary(bitmapHex);
    
    int datagramLength = 2 + isoCode.length() + bitmap.length + data.length();
    
    ByteBuffer buffer = ByteBuffer.allocate(datagramLength);
    buffer.order(ByteOrder.BIG_ENDIAN).putShort((short)datagramLength);
    buffer.put(isoCode.getBytes(encodingName));
    buffer.put(bitmap);
    buffer.put(data.getBytes(encodingName));
    
    byte[] output = buffer.array();
    

    【讨论】:

      猜你喜欢
      • 2016-06-23
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      • 2011-10-04
      • 1970-01-01
      • 1970-01-01
      • 2013-05-08
      相关资源
      最近更新 更多