Szukam sposobu na konwersję długiego łańcucha (ze zrzutu), który reprezentuje wartości szesnastkowe w tablicy bajtów.
Nie potrafiłbym sformułować tego lepiej niż osoba, która zadała to samo pytanie tutaj .
Ale aby zachować oryginalność, sformułuję to po swojemu: załóżmy, że mam ciąg "00A0BF"
, który chciałbym interpretować jako
byte[] {0x00,0xA0,0xBf}
co powinienem zrobić?
Jestem nowicjuszem w Javie i skończyłem na używaniu BigInteger
wiodących zer szesnastkowych. Ale myślę, że to brzydkie i jestem pewien, że brakuje mi czegoś prostego.
BigInteger
tutaj .String.getBytes()
nie będzie działać tak, jak myślisz. Musiałem nauczyć się tego na własnej skórze.if ("FF".getBytes() != "ff".getBytes()) { System.out.println("Try again"); }
Odpowiedzi:
Oto rozwiązanie, które moim zdaniem jest lepsze niż jakiekolwiek dotychczas opublikowane:
Powody, dla których jest to poprawa:
Bezpieczny z wiodącymi zerami (w przeciwieństwie do BigInteger) i z ujemnymi wartościami bajtów (w przeciwieństwie do Byte.parseByte)
Nie konwertuje ciągu na
char[]
ani nie tworzy obiektów StringBuilder i String dla każdego bajtu.Brak zależności bibliotek, które mogą być niedostępne
Dodawaj sprawdzanie argumentów za pomocą
assert
wyjątków, jeśli argument nie jest bezpieczny.źródło
Jednowarstwowe:
Ostrzeżenia :
eckes
)Fabian
za odnotowanie tego), ale możesz po prostu wziąć kod źródłowy, jeślijavax.xml
z jakiegoś powodu brakuje systemu . Dzięki @Bert Regelink
za wyodrębnienie źródła.źródło
java.se
zestawu root, więc spowoduje,ClassNotFoundException
że nie zostanie określony--add-modules java.se.ee
javax.xml.bind.DatatypeConverter
już zapewnia metodę kodowania / dekodowania danych Base64. ZobaczparseBase64Binary()
iprintBase64Binary()
.DataTypeConverter
, Java SE 11 całkowicie usunęła JAXB API i jest teraz dołączona tylko do Java EE. Możesz również dodać go jako zależność od Maven, jak sugerowano tutaj: stackoverflow.com/a/43574427/7347751Klasa Hex we wspólnym kodzie powinna to zrobić.
http://commons.apache.org/codec/
źródło
Możesz teraz użyć BaseEncoding w
guava
celu osiągnięcia tego.Aby to odwrócić, użyj
źródło
Właściwie myślę, że BigInteger jest rozwiązaniem, które jest bardzo miłe:
Edycja: Nie jest bezpieczne dla zer wiodących , jak zauważa plakat.
źródło
Dla tych, którzy są zainteresowani faktycznym kodem za One- liners z FractalizeR (potrzebowałem tego, ponieważ javax.xml.bind nie jest dostępny dla Androida (domyślnie)), pochodzi on z com.sun.xml.internal.bind. DatatypeConverterImpl.java :
źródło
HexBinaryAdapter
Umożliwia Marszałek i unmarshal pomiędzyString
ibyte[]
.To tylko przykład, który wpisałem ... Właściwie używam go takim, jaki jest i nie muszę tworzyć osobnej metody korzystania z niego.
źródło
Oto metoda, która faktycznie działa (na podstawie kilku wcześniejszych częściowo poprawnych odpowiedzi):
Jedynym możliwym problemem, jaki widzę, jest to, czy łańcuch wejściowy jest wyjątkowo długi; wywołanie metody toCharArray () tworzy kopię wewnętrznej tablicy łańcucha.
EDYCJA: Aha, a przy okazji, bajty są podpisywane w Javie, więc ciąg wejściowy konwertuje na [0, -96, -65] zamiast [0, 160, 191]. Ale pewnie już to wiesz.
źródło
W Androidzie, jeśli pracujesz z hexem , możesz wypróbować okio .
proste użycie:
i wynik będzie
źródło
BigInteger()
Metoda z java.math jest bardzo powolny i nie recommandable.Integer.parseInt(HEXString, 16)
może powodować problemy z niektórymi postaciami bez konwersji na cyfrę / liczbę całkowitą
dobrze działająca metoda:
Funkcjonować:
Miłej zabawy, powodzenia
źródło
EDYCJA: jak wskazał @mmyers, ta metoda nie działa na danych wejściowych zawierających podciągi odpowiadające bajtom z ustawionym wysokim bitem („80” - „FF”). Wyjaśnienie znajduje się pod adresem Bug ID: 6259307 Byte.parseByte nie działa zgodnie z reklamą w dokumentacji SDK .
źródło
Oto, co warto, oto kolejna wersja, która obsługuje łańcuchy o nieparzystej długości, bez uciekania się do łączenia łańcuchów.
źródło
Zawsze stosowałem taką metodę
ta metoda dzieli wartości szesnastkowe rozdzielane spacjami, ale nie byłoby trudno zmusić ją do podzielenia łańcucha według innych kryteriów, na przykład na grupy dwóch znaków.
źródło
Byte
/byte
: najwyższy zestaw bitów bez wiodącego -)Lubię rozwiązanie Character.digit, ale oto jak je rozwiązałem
źródło
Kod przedstawiony przez Bert Regelink po prostu nie działa. Spróbuj wykonać następujące czynności:
źródło
Znalazłem Kernel Panic, który ma najbardziej przydatne rozwiązanie, ale napotkałem problemy, jeśli ciąg szesnastkowy był liczbą nieparzystą. rozwiązał to w ten sposób:
Dodaję do tablicy pewną liczbę liczb szesnastkowych, więc przekazuję odwołanie do tablicy, której używam, i int potrzebuję przekonwertować i zwracam względną pozycję następnego numeru szesnastkowego. Zatem końcowa tablica bajtów ma [0] liczbę par szesnastkowych, [1 ...] par szesnastkowych, a następnie liczbę par ...
źródło
W oparciu o głosowane op, następujące elementy powinny być nieco bardziej wydajne:
Ponieważ: wstępna konwersja do tablicy char oszczędza sprawdzanie długości w charAt
źródło
Jeśli preferujesz strumienie Java 8 jako swój styl kodowania, możesz to osiągnąć, używając tylko prymitywów JDK.
Te
, 0, s2.size()
parametry w funkcji kolektor złączyć można pominąć, jeśli nie przeszkadza wzrokIOException
.źródło
źródło
Moje formalne rozwiązanie:
Jest jak funkcja hex2bin () PHP ale w stylu Java.
Przykład:
źródło
Późno na imprezę, ale połączyłem powyższą odpowiedź DaveL z klasą z odwrotnym działaniem - na wypadek, gdyby to pomogło.
I klasa testowa JUnit:
źródło
Wiem, że to bardzo stary wątek, ale nadal lubię dodawać mój grosz.
Jeśli naprawdę muszę zakodować prosty ciąg szesnastkowy do konwertera binarnego, chciałbym to zrobić w następujący sposób.
źródło
Zdecydowanie nie najczystsze rozwiązanie. Ale to działa dla mnie i jest dobrze sformatowane:
Wyjście:
źródło
Myślę, że zrobię to za ciebie. Połączyłem go z podobną funkcją, która zwróciła dane jako ciąg znaków:
źródło
Dla mnie to było rozwiązanie, HEX = „FF01”, a następnie podzielony na FF (255) i 01 (01)
źródło