Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Вот решение, что я думаю, лучше, чем кто-либо отправленный до сих пор:
public static byte[] hexStringToByteArray(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;
}
Причины, почему это - улучшение:
Безопасный с начальными нулями (в отличие от BigInteger) и с отрицательными значениями байта (в отличие от Byte.parseByte)
не преобразовывает Строку в char[]
или создает объекты StringBuilder и Строки для каждого байта.
зависимости библиотеки No, которые не могут быть доступны
, Не стесняются добавлять проверку аргументов через assert
или исключения, если аргумент, как известно, не безопасен.
Я думаю, сделает это для Вас. Я починил его от подобной функции, которая возвратила данные как строку:
private static byte[] decode(String encoded) {
byte result[] = new byte[encoded/2];
char enc[] = encoded.toUpperCase().toCharArray();
StringBuffer curr;
for (int i = 0; i < enc.length; i += 2) {
curr = new StringBuffer("");
curr.append(String.valueOf(enc[i]));
curr.append(String.valueOf(enc[i + 1]));
result[i] = (byte) Integer.parseInt(curr.toString(), 16);
}
return result;
}
Я всегда использовал метод как
public static final byte[] fromHexString(final String s) {
String[] v = s.split(" ");
byte[] arr = new byte[v.length];
int i = 0;
for(String val: v) {
arr[i++] = Integer.decode("0x" + val).byteValue();
}
return arr;
}
этот метод разделения на пространстве разграниченные шестнадцатеричные значения, но не было бы трудно заставить его разделить строку на любых других критериях такой как в группировки двух символов.
РЕДАКТИРОВАНИЕ: как указано @mmyers, этот метод не работает над входом, который содержит подстроки, соответствующие байтам с высоким набором битов ("80" - "FF"). Объяснение в идентификатор Ошибки: 6259307 Byte.parseByte, не работающие, как рекламируется в Документации SDK .
public static final byte[] fromHexString(final String s) {
byte[] arr = new byte[s.length()/2];
for ( int start = 0; start < s.length(); start += 2 )
{
String thisByte = s.substring(start, start+2);
arr[start/2] = Byte.parseByte(thisByte, 16);
}
return arr;
}
Вот метод, который на самом деле работает (на основе нескольких предыдущих полукорректных ответов):
private static byte[] fromHexString(final String encoded) {
if ((encoded.length() % 2) != 0)
throw new IllegalArgumentException("Input string must contain an even number of characters");
final byte result[] = new byte[encoded.length()/2];
final char enc[] = encoded.toCharArray();
for (int i = 0; i < enc.length; i += 2) {
StringBuilder curr = new StringBuilder(2);
curr.append(enc[i]).append(enc[i + 1]);
result[i/2] = (byte) Integer.parseInt(curr.toString(), 16);
}
return result;
}
единственная возможная проблема, которую я вижу, - то, если входная строка чрезвычайно длинна; вызов toCharArray () делает копию внутреннего массива строки.
РЕДАКТИРОВАНИЕ: О, и между прочим, байты подписываются в Java, таким образом, Ваша входная строка преобразовывает в [0,-96,-65] вместо [0, 160, 191]. Но Вы, вероятно, уже знали это.
На самом деле я думаю, что BigInteger является решением, очень хорошо:
new BigInteger("00A0BF", 16).toByteArray();
Редактирование: Не безопасный для начальных нулей , как отмечено плакатом.
Шестнадцатеричный класс в кодеке свободного городского населения должен сделать это для Вас.
http://commons.apache.org/codec/
import org.apache.commons.codec.binary.Hex;
...
byte[] decoded = Hex.decodeHex("00A0BF");
// 0x00 0xA0 0xBF
Метод BigInteger ()
из java.math очень медленный и не рекомендуется.
Integer.parseInt (HEXString, 16)
может вызвать проблемы с некоторые персонажи без преобразование в число / целое число
Хорошо работающий метод:
Integer.decode("0xXX") .byteValue()
Функция:
public static byte[] HexStringToByteArray(String s) {
byte data[] = new byte[s.length()/2];
for(int i=0;i < s.length();i+=2) {
data[i/2] = (Integer.decode("0x"+s.charAt(i)+s.charAt(i+1))).byteValue();
}
return data;
}
Удачи, удачи
public static byte[] hex2ba(String sHex) throws Hex2baException {
if (1==sHex.length()%2) {
throw(new Hex2baException("Hex string need even number of chars"));
}
byte[] ba = new byte[sHex.length()/2];
for (int i=0;i<sHex.length()/2;i++) {
ba[i] = (Integer.decode(
"0x"+sHex.substring(i*2, (i+1)*2))).byteValue();
}
return ba;
}
Мне нравится решение Character. digit, но вот как я решил эту проблему
public byte[] hex2ByteArray( String hexString ) {
String hexVal = "0123456789ABCDEF";
byte[] out = new byte[hexString.length() / 2];
int n = hexString.length();
for( int i = 0; i < n; i += 2 ) {
//make a bit representation in an int of the hex value
int hn = hexVal.indexOf( hexString.charAt( i ) );
int ln = hexVal.indexOf( hexString.charAt( i + 1 ) );
//now just shift the high order nibble and add them together
out[i/2] = (byte)( ( hn << 4 ) | ln );
}
return out;
}