Garip bir karakteri nasıl tanımlayabilirim?


10

Çalıştığım bir dosyada bulduğum garip bir karakteri belirlemeye çalışıyorum:

$ cat file
�
$ od file
0000000 005353
0000002
$ od -c file
0000000 353  \n
0000002
$ od -x file
0000000 0aeb
0000002

Dosya ISO-8859 kodlaması kullanıyor ve UTF-8 biçimine dönüştürülemiyor:

$ 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

Asıl sorum buradaki çıktıyı nasıl yorumlayabilirim od? Bana farklı karakter gösterimleri arasında çevirmek sağlar bu sayfayı kullanmaya çalışıyorum , ama bana 005353bir "Hex kod noktası" olarak doğru görünmüyor ve 0aebbir "Hex kod noktası" olarak , yine yanlış görünüyor olduğunu söylüyor .

Yani, nasıl üç seçenekten birini kullanabilirsiniz (edebilirsiniz 355, 005353ya da 0aebtemsil ettikleri gerekiyordu ne karakter öğrenmek için)?

Ve evet, Unicode araçlarıyla denedim ama geçerli bir UTF karakteri gibi görünmüyor:

$ 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

Unicode U + FFFD karakterinin açıklamasını anlarsam, gerçek bir karakter değil, bozuk bir karakter için bir yer tutucu. Dosya aslında UTF-8 kodlanmamış olduğundan mantıklı.


5
EB de δ olabilir kod sayfası 437 yılında ya Ù kod sayfası 850 yılında veya e 8859-1 ; bunlardan herhangi biri anlamlı olur mu? ( iconvkaynak karakter kümesini belirtmediğiniz için şikayet eder, bu nedenle muhtemelen UTF-8 olan varsayılanınızı kullanır.)
Stephen Kitt

@StephenKitt evet, ëveriler başka bir programda kullanıldığında gördüğüm şey! Ama bunu nasıl bilebilirim? Verilerimde bir yerde değil mi? Nasıl buldun? Oh çalıştı iconvile -f ISO-8859ancak şikayetçi conversion from supported` değildir ISO-8859' .
terdon

1
Ahh! ebGördüm, sadece kullanmam ve 0xonaltılı göstergeyi ya da her neyse görmezden gelmem gerekiyordu. Bu tür şeyleri bilmemem derin. @StephenKitt açıklayan bir cevap gönderebilir misiniz?
terdon

5
Buradaki önemli hatanız ISO-8859'un bir kodlamanın adı olmamasıdır. Bu bir kodlama ailesi; Görünüşe göre, aradığınız ISO-8859-1.
tripleee

1
O zaman iconvbaşarılı olurdunuz; ve / veya örneğin Wikipedia'da bakmış olabilirsiniz. Bu çok özel kodlama için, fileformat.info/info/unicode/char/00eb/index.htm da çalışır (Unicode, 128-255 aralığında ISO-8859-1'e eşdeğerdir, ancak elbette hiçbir UTF kodlaması onunla uyumlu değildir ).
tripleee

Yanıtlar:


22

Dosyanız iki bayt içerir, onaltılık EB ve 0A. Dosyanın, ISO-8859-1 gibi karakter başına bir bayt içeren bir karakter kümesi kullanıyor olması muhtemeldir ; bu karakter kümesinde EB şu şekildedir:

$ printf "\353\n" | iconv -f ISO-8859-1
ë

Diğer adaylar kod sayfası 437'de Ù, kod sayfası 850'de Ù olur ...

od -xendianness nedeniyle bu durumda çıktı kafa karıştırıcı; -t x1tek bayt kullanan daha iyi bir seçenek :

$ printf "\353\n" | od -t x1
0000000 eb 0a
0000002

od -xod -t x2bir seferde iki bayt okuyan haritalar ve küçük endian sistemlerde baytları ters sırayla çıkarır.

Geçerli bir UTF-8 olmayan (veya UTF-8 dosyası olarak yorumlandığında hiçbir anlam ifade etmeyen) böyle bir dosyayla karşılaştığınızda, kodlamasını (ve karakter kümesini) otomatik olarak belirlemenin kusursuz bir yolu yoktur. Bağlam yardımcı olabilir: eğer son birkaç on yıl içinde bir Batı PC'de üretilmiş bir dosyaysa, ISO-8859-1, -15 (Euro varyantı) veya Windows-1252'de kodlanmış olması ihtimali yüksektir; bundan büyükse, CP-437 ve CP-850 muhtemelen adaydır. Doğu Avrupa sistemlerinden ya da Rus sistemlerinden ya da Asya sistemlerinden gelen dosyalar hakkında çok şey bilmediğim farklı karakter kümeleri kullanır. Sonra EBCDIC var ... bilen iconv -ltüm karakter setlerini listeleyecek iconvve oradan deneme yanılma yoluyla devam edebilirsiniz.

(Bir noktada CP-437 ve ATASCII'nin çoğunu ezbere biliyordum, günlerdi.)


1
Tamam, bağlandığınız wikipedia sayfasında, ve ëolarak tanımlandığını görebiliyorum . Bunlar ekstra ne ? Ve neden çıktıdan beklediğim gibi değil ? Karakteri tanımlamak için çıktıyı nasıl kullanabileceğim hakkında daha genel bir cevap almaya çalışıyorum . Onaltılık kodları yorumlamak ve / veya bilinmeyen bir karakteri (kodlama ve başka bir şey) tanımlamak için hangi bilgilere ihtiyaç duyulduğunu açıklayabilir misiniz? 00EB23400355odod
terdon

EB sekizli olarak 353'tür (355 değil). Genelleştirmeye çalışacağım ...
Stephen Kitt

Üzgünüz, demek istediğim 353. Yani 353 ondalık değil sekizli bir temsildir. Ahh.
terdon

1
Evet, “o” odsekizli ;-) anlamına gelir.
Stephen Kitt

1
Her durumda, (U + FFFD) terminal emülatörü tarafından UTF-8'de geçerli bir karakter oluşturmayan bu 0xeb baytının yerine geçecektir. Neden uniprops $(cat file)(eksik tırnaklar btw) bunu (bu unipropskomut hakkında bilmiyorum) rapor olacağını açık değil . unicode "$(cat file)"Debian Sequence '\xeb' is not valid in charset 'UTF-8'beklediğim gibi çıktı .
Stéphane Chazelas

5

Not odkısaltmasıdır sekizlik dökümü yüzden 005353, sekizlik kelime olarak iki bayt olan od -xbir 0aebkelime olarak onaltılık ve dosyanızın gerçek içeriği iki bayt olan ebve 0aonaltılık, bu sırada.

Yani her ikisi de 005353ve 0aebsadece onaltılık kod noktası olarak yorumlanamaz.

0asatır beslemesidir (LF) ve ebkodlamanıza bağlıdır. filesadece kodlamayı tahmin ediyor, her şey olabilir. Dosyanın nereden geldiği vb. Daha fazla bilgi olmadan bulmak zor olacaktır.


Bunun, kod noktalarının (veya hex, gerçekten) nasıl çalıştığını anlamamış olduğumun farkındayım, ama bunu nasıl bilebilirim? Genellikle od -canladığım çıktılar ürettiğim için kullanıyorum . 355Üreten karakteri karakteri tanımlamak için nasıl kullanabilirdim ? Ve neden yazdırıyor 0aebyerine eb0aeğer 0asatır mı?
terdon

@terdon endianness ... Güncellenmiş cevabımı görün.
Stephen Kitt

2

Metin dosyalarının% 100 doğrulukla tahmin etmek imkansızdır.

Tanımlanmış açık karakter bilgisi olmadığında chardet , firefox , file -i gibi araçlar (örneğin, bir HTML bir meta karakter kümesi içeriyorsa = ..., işler daha kolay), metin yeterince büyük.

Aşağıda, chardet( pip install chardet/ apt-get install python-chardetgerekirse) ile karakter kümesi algılamayı göstereceğim .

$ echo "in Noël" | iconv -f utf8 -t latin1  | chardet
<stdin>: windows-1252 with confidence 0.73

İyi charset aday yaptıktan sonra biz kullanabilirsiniz iconv, recode(benim durumumda utf-8 içinde) "aktif" charset dosya charset değiştirmek veya benzer ve doğru tahmin olmadığını görmek ...

iconv -f windows-1252  -t utf-8 file

Bazı karakter kümelerinin (iso-8859-3, iso-8859-1 gibi) ortak birçok karakterleri vardır - bazen mükemmel karakter kümesini bulup bulmadığımızı görmek kolay değildir ...

Dolayısıyla, ilgili metinle (ör. XML) ilişkili meta verilerin olması çok önemlidir.


Hmm. Burada çoğaltamıyorum, sadece çöküyor. Ama her durumda, bu sadece dosyanın kodlamasını söylemiyor mu? Benim sorunum dosyanın kodlamasını değil karakteri tanımlamak . Zaten biliyordum.
terdon

1
Maalesef soruyu anlayamadım (her zamanki sorunum karakter setini tanımlamak). Eğer şimdi kodlama, iconv -f ... -t utf-8 size karakterleri gösterecek?
JJoao

Hayır. Kodlamayı hemen orada gösteriyorum. Bu kodlama tarafından desteklenmeyen belirli bir karakter vardı ve tanımlamaya çalıştığım karakter.
terdon

1
Iso-8859 kodlama değil! kodlama iso-8850-1. iso-8859 çeşitli chaset tanımlarını içeren bir iso standardıdır. Deneyinfile -i ...
JJoao

1
@terdon, ısrar ettiğim için üzgünüm, ama denediğiniz tüm numaralar doğru karakterle çalışıyor. Örn: iconv -f ISO-8859-1 -t UTF-8 file
JJoao

0
#!/bin/bash
#
# Search in a file, a known (part of a ) String (i.E.: Begrüßung),
# by testing all encodings
#
[[ $# -ne 2 ]] && echo "Usage: encoding-finder.sh FILE fUnKy_CHAR_FOR_SURE_IN_FILE" && exit
FILE=$1
PATTERN=$2
for enc in $( iconv -l | sed 's/..$//') 
do 
    iconv -f $enc -t UTF-8 $FILE  2>/dev/null | grep -m 1 $PATTERN && echo $enc 
done 

Örneğin Begrung Kelimesi için bir dosya alırsam, Begrüßung'un kastedilebileceğini söyleyebilirim. Bu yüzden bilinen tüm kodlayıcılarla dönüştürüyorum ve bir tane bulunup bulunmadığına bakıyorum, bu da düzgün bir şekilde dönüştürüyor.

Genellikle, uygun görünen birden fazla kodlama vardır.

Daha uzun dosyalar için yüzlerce sayfayı dönüştürmek yerine bir parçacığı kesebilirsiniz.

Ben de derdim

encodingfinder.sh FILE Begrüßung

ve senaryo testleri, ister "Begrüßung" üreten, bilinen kodlamalar ile dönüştürülerek dönüştürülür.

Bu karakterleri bulmak için genellikle daha az yardımcı olur, çünkü korkak karakterler genellikle öne çıkar. Bağlamdan, aranacak doğru sözcük genellikle çıkarılabilir. Ama biz bir hexeditor ile kontrol etmek istemiyoruz, bunun bayt ne olduğunu ve sonra suçlu bulmak için sonsuz kodlama tabloları ziyaret etmek istemiyoruz. :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.