Mam pewne dane zakodowane w UTF-8, które znajdują się w szeregu elementów Uint8Array w JavaScript. Czy istnieje skuteczny sposób na zdekodowanie ich do zwykłego ciągu javascript (uważam, że JavaScript używa 16-bitowego Unicode)? Nie chcę dodawać jednego znaku na raz, ponieważ konkaternacja ciągów będzie obciążać procesor.
javascript
Jack Wester
źródło
źródło
u8array.toString()
podczas odczytu plików z BrowserFS, które ujawniają obiekt Uint8Array podczas wywoływaniafs.readFile
.toString
onUint8Array
zwraca liczby oddzielone przecinkami, takie jak"91,50,48,49,57,45"
(Chrome 79)Odpowiedzi:
TextEncoder
iTextDecoder
ze standardu Encoding , który jest wypełniany przez bibliotekę stringencoding , konwertuje między ciągami a ArrayBuffers:źródło
npm install text-encoding
,var textEncoding = require('text-encoding'); var TextDecoder = textEncoding.TextDecoder;
. Nie, dziękuję.utf-8
. WięcTextEncoder
argument jest niepotrzebny!TextEncoder
/TextDecoder
API w wersji 11, więc nie ma potrzeby instalowania żadnych dodatkowych pakietów, jeśli celem jest tylko bieżąca wersja Node.To powinno działać:
Jest trochę czystszy jak inne rozwiązania, ponieważ nie używa żadnych hacków ani nie jest zależny od funkcji Browser JS, np. Działa również w innych środowiskach JS.
Sprawdź demo JSFiddle .
Zobacz także powiązane pytania: tutaj i tutaj
źródło
fromUTF8Array([240,159,154,133])
Okazuje się pusty (podczasfromUTF8Array([226,152,131])→"☃"
)Oto czego używam:
źródło
RangeError
większych tekstów. „Przekroczono maksymalny rozmiar stosu połączeń”SCRIPT28: Out of stack space
gdy podaję 300 + k znaków, lubRangeError
dla Chrome 39. Firefox 33 jest w porządku. 100 + k działa dobrze ze wszystkimi trzema.Znajduje się w jednej z przykładowych aplikacji Chrome, chociaż jest to przeznaczone dla większych bloków danych, w przypadku których konwersja asynchroniczna nie przeszkadza.
źródło
W Node „
Buffer
instancje są równieżUint8Array
instancjami ”, więcbuf.toString()
działa w tym przypadku.źródło
Buffer
również świadomy Uint8Array. Dzięki!Buffer.from(uint8array).toString('utf-8')
Rozwiązanie podane przez Alberta działa dobrze, o ile podana funkcja jest wywoływana rzadko i jest używana tylko dla tablic o niewielkich rozmiarach, w przeciwnym razie jest rażąco nieefektywna. Oto ulepszone rozwiązanie w języku waniliowym JavaScript, które działa zarówno w przypadku węzła, jak i przeglądarek, i ma następujące zalety:
• Działa wydajnie dla wszystkich rozmiarów tablic oktetów
• Nie generuje pośrednich łańcuchów jednorazowego użytku
• Obsługuje 4-bajtowe znaki w nowoczesnych silnikach JS (w przeciwnym razie zastępowane jest „?”)
źródło
Zrób to, co powiedział @Sudhir, a następnie, aby uzyskać ciąg znaków z rozdzielonej przecinkami listy liczb, użyj:
To da ci żądany ciąg, jeśli nadal jest istotny
źródło
String.fromCharCode.apply(null, unitArr);
. Jak wspomniano, nie obsługuje kodowania UTF8, ale czasami jest to wystarczająco proste, jeśli potrzebujesz tylko obsługi ASCII, ale nie masz dostępu do TextEncoder / TextDecoder.Jeśli nie możesz użyć interfejsu API TextDecoder, ponieważ nie jest on obsługiwany w przeglądarce IE :
źródło
Wypróbuj te funkcje,
źródło: https://gist.github.com/tomfa/706d10fed78c497731ac , kudos to Tomfa
źródło
Byłem sfrustrowany, widząc, że ludzie nie pokazują, jak postępować w obie strony, ani nie pokazują, że wszystko działa na żadnych trywialnych łańcuchach UTF8. Znalazłem post na codereview.stackexchange.com, który zawiera kod, który działa dobrze. Użyłem go, aby zamienić starożytne runy w bajty, przetestować trochę kripo na bajtach, a następnie przekształcić je z powrotem w ciąg. Działający kod jest na github tutaj . Zmieniłem nazwy metod dla przejrzystości:
Test jednostkowy używa tego ciągu UTF-8:
Zwróć uwagę, że długość ciągu wynosi tylko 117 znaków, ale długość bajtu po zakodowaniu to 234.
Jeśli odkomentuję wiersze console.log, widzę, że dekodowany ciąg jest tym samym ciągiem, który został zakodowany (z bajtami przekazanymi przez tajny algorytm udostępniania Shamira!):
źródło
String.fromCharCode.apply(null, chars)
błąd, jeślichars
jest za duży.But beware: by using apply this way, you run the risk of exceeding the JavaScript engine's argument length limit. The consequences of applying a function with too many arguments (that is, more than tens of thousands of arguments) varies across engines. (The JavaScriptCore engine has hard-coded argument limit of 65536.
W NodeJS mamy dostępne bufory, a konwersja ciągów za ich pomocą jest naprawdę łatwa. Co więcej, łatwo jest przekonwertować Uint8Array na bufor. Wypróbuj ten kod, działał dla mnie w Node w zasadzie dla każdej konwersji związanej z Uint8Arrays:
Po prostu wyodrębniamy ArrayBuffer z Uint8Array, a następnie konwertujemy go na odpowiedni bufor NodeJS. Następnie konwertujemy Buffer na łańcuch (możesz wrzucić kodowanie hex lub base64, jeśli chcesz).
Jeśli chcemy przekonwertować z powrotem na Uint8Array z łańcucha, zrobimy to:
Pamiętaj, że jeśli zadeklarowałeś kodowanie takie jak base64 podczas konwersji na ciąg, musisz użyć,
Buffer.from(str, "base64")
jeśli użyłeś base64 lub innego używanego kodowania.To nie zadziała w przeglądarce bez modułu! Bufory NodeJS po prostu nie istnieją w przeglądarce, więc ta metoda nie będzie działać, chyba że dodasz funkcję bufora do przeglądarki. To rzeczywiście bardzo łatwe do zrobienia, chociaż, wystarczy użyć modułu jak ten , który jest zarówno małe i szybko!
źródło
`
źródło
Używam tego fragmentu kodu Typescript:
Usuń adnotacje typu, jeśli potrzebujesz wersji JavaScript. Mam nadzieję że to pomoże!
źródło