iconv generujący UTF-16 z BOM

11

Zainspirowany tym pytaniem , czy mogę użyć iconvpolecenia do wygenerowania wyjścia UTF-16 z BOM i określoną endianią?

iconvTekst nawróceni polecenie z jednego kodowania do innego.

Na przykład:

echo hello | iconv -f ascii -t utf-16

generuje reprezentację UTF-16 dla "hello\n".

Pliki UTF-16 często, ale nie zawsze, zaczynają się od znaku Byte Order Mark (BOM), który jest 2-bajtowym kodowaniem znaku Unicode U+FEFF. Możesz określić endianowość pliku UTF-16 z BOM, sprawdzając, czy pierwsze dwa bajty to FE FFlub FF FE.

iconvKomenda ma kilka opcji do generowania UTF-16 dane wyjściowe:

$ iconv --list | grep -i utf-16
UTF-16//
UTF-16BE//
UTF-16LE//

To polecenie:

echo hello | iconv -f ascii -t utf-16be

generuje big-endian UTF-16 bez BOM ; wydaje się zakładać, że jeśli określono endianness, nie trzeba wskazywać go w danych wyjściowych. Podobnie, utf-16legeneruje little-endian UTF-16 bez BOM.

To:

echo hello | iconv -f ascii -t utf-16

generuje (w moim systemie x86 Ubuntu) little-endian UTF-16 z BOM - ale widziałem raport o podobnym poleceniu generującym big-endian UTF-16 z BOM, nawet w systemie little-endian.

Zawsze mogę ręcznie użyć BOM utf-16belub utf-16leuzupełnić go, ale szukam rozwiązania, które po prostu używa iconvpolecenia.

Innym obejściem, jeśli wiesz, co -t utf-16powoduje endianizm , jest:

echo hello | iconv -f ascii -t utf-16 | dd conv=swab 2>/dev/null

Co ja lubię do użytku jest coś takiego:

iconv -f ascii -t utf-16bebom # big-endian with BOM
iconv -f ascii -t utf-16lebom # little-endian with BOM

ale iconvtego nie obsługuje.

EDYTOWAĆ :

Czy ktoś mający dostęp do systemu Mac OSX x86 może opublikować komentarz pokazujący (skopiuj i wklej) dane wyjściowe następującego polecenia?

echo hello | iconv -f ascii -t utf-16 | od -x
Keith Thompson
źródło
1
LM zmniejsza przenośność danych, ale można je dodać w ten sposób
RedGrittyBrick
@RedGrittyBrick: Jak to zmniejsza przenośność (szczególnie dla UtF-16)? Wiem, że mogę wygenerować BOM w sposób esencjonalny; Szukam sposobu, aby to zrobić, używając iconv- i zastanawiam się, dlaczego -t utf-16wydaje się, że endianness nie jest określony.
Keith Thompson
Wydaje mi się, że iconv zakłada bieżące porządkowanie bajtów platformy, jeśli nie zostanie to wyraźnie określone. Na niektórych platformach innych niż Windows niektóre narzędzia do przetwarzania tekstu nie oczekują zestawień BOM i dlatego robią coś niewłaściwego. Przykładem może być łączenie plików tekstowych lub używanie szablonów opartych na plikach do tworzenia treści. „W przypadku zarejestrowanych przez IANA zestawów znaków UTF-16BE i UTF-16LE nie należy używać znaku kolejności bajtów, ponieważ nazwy tych zestawów znaków już określają kolejność bajtów”
RedGrittyBrick
To pytanie pokazuje iconv -f UTF-8 -t UTF-16, uruchom na systemie little-endian (MacOS), generując big-endian UTF-16 z BOM, co wydaje się bardzo dziwne.
Keith Thompson

Odpowiedzi:

9

Nie , jeśli podasz kolejność bajtów, iconvnie wstawi BOM.

To pochodzi z Konsorcjum Unicode

P: Jak powinienem postępować z BOM?

Odp .: Oto kilka wskazówek, których należy przestrzegać:

  1. Określony protokół (np. Konwencje Microsoft dla plików .txt) może wymagać użycia BOM w niektórych strumieniach danych Unicode, takich jak pliki. Jeśli musisz dostosować się do takiego protokołu, użyj BOM.
  2. Niektóre protokoły zezwalają na opcjonalne LM w przypadku nieoznaczonego tekstu. W takich przypadkach
    • Tam, gdzie wiadomo, że strumień danych tekstowych to zwykły tekst, ale o nieznanym kodowaniu, BOM może być użyty jako podpis. Jeśli nie ma BOM, kodowanie może być cokolwiek.
    • Tam, gdzie wiadomo, że strumień danych tekstowych jest zwykłym tekstem Unicode (ale nie który endian), BOM może być użyty jako podpis. Jeśli nie ma BOM, tekst należy interpretować jako big-endian.
  3. Niektóre protokoły bajtowe oczekują znaków ASCII na początku pliku. Jeśli UTF-8 jest używany z tymi protokołami, należy unikać korzystania z BOM jako podpisu formularza kodowania.
  4. Tam, gdzie znany jest dokładny typ strumienia danych (np. Unicode big-endian lub Unicode little-endian), BOM nie powinien być używany. W szczególności, ilekroć strumień danych zostanie zadeklarowany jako UTF-16BE, UTF-16LE, UTF-32BE lub UTF-32LE, nie wolno używać BOM .

(mój nacisk)

Oczekuję, że iconvstara się być wierny ostatnim z tych wytycznych.


Aktualizacja.

Dygresja

W mojej opinii:

  1. Opcja określenia BOM byłaby z pewnością użyteczną dodatkową funkcją dla iconv.

  2. Plik UTF-16LE bez BOM jest użyteczny w systemie Windows, choć czasem wymaga to dodatkowego wysiłku. Na przykład okno dialogowe Otwórz plik Notatnika pozwala wybrać „Unicode”, który jest nazwą Microsoftu dla „UTF-16LE” i (co nie jest zaskoczeniem) wydaje się działać na plikach bez BOM.

  3. Mogę otworzyć plik testowy UTF-16LE (bez BOM) lub plik testowy UTF-8 (bez BOM) w Notatniku Windows (XP) w zwykły sposób, np. Poprzez dwukrotne kliknięcie nazwy pliku w Eksploratorze. Wydaje mi się to przydatne. Wiem, że czasami system Windows nieprawidłowo zgaduje kodowanie - w takim przypadku musisz powiedzieć Notatnikowi o kodowaniu podczas otwierania pliku. Ta niedogodność oznacza, że ​​dołączanie BOM jest lepsze w przypadku plików tekstowych przeznaczonych do użycia w systemie Windows.

  4. Jeśli konkretna aplikacja nie będzie działać z niczym innym niż plik UTF-16LE z BOM, to zgodziłbym się, że plik UTF-16LE bez BOM nie nadaje się do tej konkretnej aplikacji.

  5. Podejrzewam, że jeśli możesz sprawić, by wszystko działało z UTF-8 (bez BOM), jest to najlepsze rozwiązanie w perspektywie długoterminowej.

Jednak odpowiedź na pytanie „ czy mogę użyć polecenia iconv do wygenerowania danych wyjściowych UTF-16 z BOM i przy określonej endianowości ” brzmi obecnie „ Nie ”.

RedGrittyBrick
źródło
1
A co z pierwszą wytyczną A.1? Jeśli chcę wygenerować plik tekstowy Unicode, który może być użyty w systemie Windows x86, powinien to być plik UTF16 typu endian z BOM .
Keith Thompson
@KeithThompson: Systemy powinny akceptować zarówno UTF16LE, jak i UTF16BE. Przynajmniej Notatnik Windows akceptuje oba, jeśli chodzi o .txt- tak długo, jak plik ma BOM.
user1686,
@KeithThompson: Zgadzam się, że wytyczna 1 powinna mieć pierwszeństwo, jednak iconv nie pozwala na określenie BOM. Odpowiedź na twoje pierwotne pytanie brzmi: „Nie”.
RedGrittyBrick
Nie była to odpowiedź, na którą liczyłem, ale odpowiedź i dokładna!
Keith Thompson
2
Ta odpowiedź pomogła mi - pomogła mi dowiedzieć się, dlaczego mnie spieprzyłem. Standardowy program Windows eksport / import z rejestru, C:\Windows\System32\reg.exeeksport UTF-16 LE Z BOM i będzie tylko do odczytu UTF-16 LE Z BOM - nie będzie czytać UTF-16 LE bez BOM i nie będzie czytać UTF-16 BE z BOM - innymi słowy, wymaga BOM podczas czytania, ale do cholery lepiej być właściwym! (Na szczęście brzmi UTF-8.)
davidbak,