3

ビットシフトを使用してバイトを16進数(charとして)に変換する方法を作成しようとしています。ただし、いくつかの予期しない結果が発生しています。数値の一部が負として返されます。Javaには符号なし整数に相当するものがないことを理解しており、これを機能させる方法について途方に暮れています。これが私のコードです:

final static char[] hex_val = "0123456789ABCDEF".toCharArray();

public static void main(String[] args) {
    byte[] bytes = {(byte) 0x58, (byte) 0x6D, (byte) 0x8F, (byte) 0xBA, (byte) 0xF5, (byte) 0x81};

    for (int i = 0; i < bytes.length; i++) {
        System.out.println("Run: " + i);
        System.out.println("First nibble: " + hex_val[(bytes[i] >> 4)]);
        System.out.println("Second nibble: " + hex_val[(bytes[i] & 0xf)]);
    }
}

出力は次のとおりです。

実行: 0 最初のニブル: 5 2 番目のニブル: 8 実行: 1 最初のニブル: 6 2 番目のニブル: D 実行: 2

続いて: スレッド「メイン」での例外 java.lang.ArrayIndexOutOfBoundsException: -8 at Test.main(Test.java:10)

String.format() を使用してこれを達成できることはわかっていますが、最小限のガベージを生成しながらすばやく動作するメソッドが必要なため、そのメソッドは使用していません。専門家への私の質問は...これを機能させるために何を変更できますか?

アップデート

私は Ted Hopp によって提案された変更を加えましたが、それはテスト メソッドで完全に機能しました。これを Android アプリに移動し、バイトを MAC アドレスに変換して、フォーマットされた MAC を含む char[] に変換しました。負の数が表示されることはなくなりましたが、ランダムな誤算と思われるものが表示されます。これが私が使用している方法です:

static final char[] parser_hex_arr = "01234567890ABCDEF".toCharArray();
static final char[] parser_mac = "  :  :  :  :  :  ".toCharArray();

void parseMac() { 
    hex_sb.setLength(0);
    for (hex_counter = 0; hex_counter < 6; hex_counter++) {
        hex_sb.append(String.format("%02X", parser_packet_bytes[parser_skip + hex_counter]));
        if (!(hex_counter == 5)) {
                hex_sb.append(":");
        }
    }

    parser_mac[0] = parser_hex_arr[ (parser_packet_bytes[parser_skip] >> 4) & 0x0f ];
    parser_mac[1] = parser_hex_arr[ (parser_packet_bytes[parser_skip] & 0xf) ];
    parser_mac[3] = parser_hex_arr[ (parser_packet_bytes[parser_skip + 1] >> 4) & 0x0f ];
    parser_mac[4] = parser_hex_arr[ (parser_packet_bytes[parser_skip + 1] & 0xf) ];
    parser_mac[6] = parser_hex_arr[ (parser_packet_bytes[parser_skip + 2]  >> 4) & 0x0f ];
    parser_mac[7] = parser_hex_arr[ (parser_packet_bytes[parser_skip + 2] & 0xf) ];
    parser_mac[9] = parser_hex_arr[ (parser_packet_bytes[parser_skip + 3]  >> 4) & 0x0f ];
    parser_mac[10] = parser_hex_arr[ (parser_packet_bytes[parser_skip + 3] & 0xf) ];
    parser_mac[12] = parser_hex_arr[ (parser_packet_bytes[parser_skip + 4] >> 4) & 0x0f ];
    parser_mac[13] = parser_hex_arr[ (parser_packet_bytes[parser_skip + 4] & 0xf) ];
    parser_mac[15] = parser_hex_arr[ (parser_packet_bytes[parser_skip + 5] >> 4) & 0x0f ];
    parser_mac[16] = parser_hex_arr[ (parser_packet_bytes[parser_skip + 5] & 0xf) ];

    Log.i("PARSER", "StringBuilder.getString() = " + hex_sb.toString() + " | parser_mac = " + String.valueOf(parser_mac));

    formatted_mac = String.valueOf(parser_mac);
}

parser_packet_bytes はパケットのバイトの byte[] 配列、parser_skip はバイトが配置されているオフセットを含む int、hex_sb は StringBuilder です。StringBuilder.toString() からの出力は String.valueOf(parser_mac) と同じはずですが、そうではありません。次に例を示します。

私/パーサー (10860): StringBuilder.getString() = AC:22:0B:40:70:41 | parser_mac = 0B:22:0A:40:70:41

私/パーサー (10860): StringBuilder.getString() = C8:F7:33:0E:7E:AF | parser_mac = B8:E7:33:0D:7D:0E

I/パーサー (10860): StringBuilder.getString() = 58:6D:8F:BA:F5:81 | parser_mac = 58:6C:8E:A0:E5:81

私/パーサー (10860): StringBuilder.getString() = AC:22:0B:40:70:41 | parser_mac = 0B:22:0A:40:70:41

私の次の質問は...なぜそれらが一致しないのですか? アイデアをお寄せいただきありがとうございます。

4

2 に答える 2