Próbuję zidentyfikować dziwną postać, którą znalazłem w pliku, z którym pracuję:
$ cat file
�
$ od file
0000000 005353
0000002
$ od -c file
0000000 353 \n
0000002
$ od -x file
0000000 0aeb
0000002
Plik korzysta z kodowania ISO-8859 i nie można go przekonwertować na format UTF-8:
$ iconv -f ISO-8859 -t UTF-8 file
iconv: conversion from `ISO-8859' is not supported
Try `iconv --help' or `iconv --usage' for more information.
$ iconv -t UTF-8 file
iconv: illegal input sequence at position 0
$ file file
file: ISO-8859 text
Moje główne pytanie brzmi: jak mogę zinterpretować wyniki od
tutaj? Próbuję użyć tej strony, która pozwala mi tłumaczyć różne reprezentacje znaków, ale mówi mi, że 005353
jako „punkt kodu Hex” wydaje się być niewłaściwy, 卓
a 0aeb
jako „punkt kodu Hex”, ૫
który ponownie wydaje się błędny .
Tak więc, w jaki sposób można zastosować jedną z trzech opcji ( 355
, 005353
lub 0aeb
), aby dowiedzieć się, jaki charakter mają oni reprezentują?
I tak, próbowałem z narzędziami Unicode, ale nie wydaje się to być poprawnym znakiem UTF:
$ uniprops $(cat file)
U+FFFD ‹�› \N{REPLACEMENT CHARACTER}
\pS \p{So}
All Any Assigned Common Zyyy So S Gr_Base Grapheme_Base Graph X_POSIX_Graph
GrBase Other_Symbol Print X_POSIX_Print Symbol Specials Unicode
jeśli rozumiem opis znaku Unicode U + FFFD, to w ogóle nie jest to prawdziwy znak, ale symbol zastępczy dla uszkodzonego znaku. Ma to sens, ponieważ plik nie jest tak naprawdę zakodowany w UTF-8.
źródło
iconv
narzeka, ponieważ nie określiłeś źródłowego zestawu znaków, więc używa twojego domyślnego, którym jest prawdopodobnie UTF-8.)ë
właśnie to widzę, gdy dane są wykorzystywane w innym programie! Ale skąd mam to wiedzieć? Czy nie jest to gdzieś w danych, które podaję? Jak to znalazłeś? Aha próbowałemiconv
ze-f ISO-8859
jednak skarżyłconversion from
ISO-8859' nie jest wspierani.eb
i zignorować0x
wskaźnik heksadecymalny lub cokolwiek to jest. Moja nieznajomość tego rodzaju rzeczy jest głęboka. Czy możesz opublikować odpowiedź wyjaśniającą, że @StephenKitt?iconv
by się udało; i / lub mogłeś to sprawdzić np. na Wikipedii. W przypadku tego bardzo specyficznego kodowania działa również fileformat.info/info/unicode/char/00eb/index.htm (Unicode odpowiada ISO-8859-1 w zakresie 128-255, choć oczywiście żadne kodowanie UTF nie jest z nim zgodne ).Odpowiedzi:
Twój plik zawiera dwa bajty, EB i 0A w trybie szesnastkowym. Prawdopodobnie plik używa zestawu znaków z jednym bajtem na znak, na przykład ISO-8859-1 ; w tym zestawie znaków EB jest ë:
Inni kandydaci byliby δ na stronie kodowej 437 , Ù na stronie kodowej 850 ...
od -x
wyniki są w tym przypadku mylące z powodu endianizmu; lepszym rozwiązaniem jest-t x1
użycie pojedynczych bajtów:od -x
mapy, dood -t x2
których odczytuje dwa bajty naraz, a w systemach little-endian wysyła bajty w odwrotnej kolejności.Gdy natrafisz na taki plik, który nie jest prawidłowy UTF-8 (lub nie ma sensu, gdy jest interpretowany jako plik UTF-8), nie ma niezawodnego sposobu automatycznego określenia jego kodowania (i zestawu znaków). Kontekst może pomóc: jeśli jest to plik wyprodukowany na zachodnim komputerze w ciągu ostatnich kilku dekad, istnieje spora szansa, że jest zakodowany w ISO-8859-1, -15 (wariant Euro) lub Windows-1252; jeśli jest starszy, CP-437 i CP-850 są prawdopodobnie kandydatami. Pliki z systemów wschodnioeuropejskich, rosyjskich lub azjatyckich używałyby różnych zestawów znaków, o których niewiele wiem. Potem jest EBCDIC ...
iconv -l
wyświetli listę wszystkich zestawów znaków,iconv
o których wie, i możesz zacząć od próby i błędu.(W pewnym momencie znałem większość CP-437 i ATASCII na pamięć, były to dni).
źródło
ë
jest to opisane jako00EB
i234
. Co to są dodatkowe00
? I dlaczego nie jest tak,355
jak się spodziewałem pood
wynikach? Próbuję uzyskać bardziej ogólną odpowiedź na temat tego, w jaki sposób mogę wykorzystać daneod
wyjściowe do zidentyfikowania postaci. Czy możesz wyjaśnić coś na temat interpretacji kodów szesnastkowych i / lub jakie informacje są potrzebne, aby móc zidentyfikować nieznany znak (kodowanie i cokolwiek innego)?353
. Tak więc 353 jest reprezentacją ósemkową, a nie dziesiętną. Argh.od
oznacza ósemkę ;-).�
(U + FFFD) byłby wyświetlany przez emulator terminala jako zamiennik tego bajtu 0xeb, który nie tworzy prawidłowego znaku w UTF-8. Nie jest jasne, dlaczegouniprops $(cat file)
(brakujące cytaty btw) miałoby to zgłosić (nie wiem o tymuniprops
poleceniu).unicode "$(cat file)"
na Debianie wykonuje dane wyjścioweSequence '\xeb' is not valid in charset 'UTF-8'
zgodnie z oczekiwaniami.Zauważ, że
od
jest skrótem od ósemkowego zrzutu , więc005353
dwa bajty jako ósemkowe słowo,od -x
są0aeb
szesnastkowe jak słowo, a rzeczywista zawartość twojego pliku to dwa bajtyeb
i0a
szesnastkowo, w tej kolejności.Więc obie
005353
i0aeb
nie można po prostu być interpretowane jako „punkt kodu hex”.0a
jest linią (LF) ieb
zależy od twojego kodowania.file
tylko zgaduje kodowanie, może to być cokolwiek. Bez dalszych informacji, skąd pochodzi plik itp., Będzie trudno go znaleźć.źródło
od -c
ponieważ daje to wynik, który mogę zrozumieć. Jak mogłem użyć355
produkujących do identyfikacji postaci? I dlaczego drukuje0aeb
zamiasteb0a
czy0a
nowa linia?Niemożliwe jest odgadnięcie ze 100% dokładnością zestawu plików tekstowych.
Narzędzia takie jak chardet , firefox , plik -i, gdy nie ma zdefiniowanych jawnych informacji o zestawie znaków (np. Jeśli HTML zawiera meta zestaw znaków = ... w głowie, rzeczy są łatwiejsze) spróbują użyć heurystyki, która nie jest taka zła, jeśli tekst jest wystarczająco duży.
Poniżej demonstruję wykrywanie zestawów znaków za pomocą
chardet
(pip install chardet
/apt-get install python-chardet
jeśli to konieczne).Po dobrym charset kandydata, możemy użyć
iconv
,recode
lub podobna do zmiany kodowania pliku do „aktywnego” zestawu znaków (w moim przypadku UTF-8) i sprawdzić, czy jest prawidłowo odgadł ...Niektóre zestawy znaków (takie jak iso-8859-3, iso-8859-1) mają wiele wspólnych znaków - czasem nie jest łatwo sprawdzić, czy znaleźliśmy idealny zestaw znaków ...
Dlatego bardzo ważne jest, aby metadane były powiązane z odpowiednim tekstem (np. XML).
źródło
iconv -f ... -t utf-8
pokaże ci znaki?iso-8850-1
. iso-8859 jest standardem iso, zawierającym kilka definicji chasetów. Spróbujfile -i ...
iconv -f ISO-8859-1 -t UTF-8 file
Jeśli otrzymam plik, który zawiera na przykład słowo Begrung, mogę wywnioskować, że Begrüßung mógł mieć na myśli. Konwertuję go więc za pomocą wszystkich znanych kodowań i sprawdzam, czy ktoś go znajdzie, co poprawnie konwertuje.
Zwykle istnieje wiele kodowań, które wydają się pasować.
W przypadku dłuższych plików możesz wyciąć fragment kodu zamiast konwertować setki stron.
Więc nazwałbym to
i testy skryptów, czy konwertując je ze znanymi kodowaniami, które z nich produkują „Begrüßung”.
Aby znaleźć takie postacie, zwykle pomaga mniej, ponieważ postacie funky często się wyróżniają. Z kontekstu można zazwyczaj wywnioskować właściwe słowo do wyszukania. Ale nie chcemy sprawdzać za pomocą hekseditora, jaki to bajt, a następnie odwiedzać niekończące się tabele kodowania, aby znaleźć naszego przestępcę. :)
źródło