UTF-7 - UTF-7

UTF-7
Języki) Międzynarodowy
Standard RFC  2152
Klasyfikacja Unicode Transformation Format , ASCII armor , kodowania o zmiennej szerokości , kodowanie Stateful
Przekształca / koduje Unicode
Poprzedzony HZ-GB-2312
zastąpiony przez UTF-8 przez 8BITMIME

UTF-7 (7- bitowy format transformacji Unicode ) to przestarzałe kodowanie znaków o zmiennej długości do reprezentowania tekstu Unicode przy użyciu strumienia znaków ASCII . Pierwotnie miał zapewniać sposób kodowania tekstu Unicode do użytku w internetowych wiadomościach e-mail, który był bardziej wydajny niż kombinacja UTF-8 z opcją „quoted-printable” .

UTF-7 (zgodnie z RFC) nie jest „ formatem transformacji Unicode ”, ponieważ definicja może kodować tylko punkty kodowe w BMP (pierwsze 65536 punktów kodowych Unicode, które nie zawierają emotikonów i wielu innych znaków). Jednakże, jeśli translator UTF-7 jest do/z UTF-16, to może (i prawdopodobnie tak robi) kodować każdą połowę zastępczą tak, jakby był to 16-bitowy punkt kodowy, a zatem może zakodować wszystkie punkty kodowe. Nie jest jasne, czy inne oprogramowanie UTF-7 (takie jak translatory do UTF-32 lub UTF-8) to obsługuje.

UTF-7 nigdy nie był oficjalnym standardem Konsorcjum Unicode . Wiadomo, że ma problemy z bezpieczeństwem, dlatego oprogramowanie zostało zmienione, aby wyłączyć jego użycie. Jest to zabronione w HTML 5 .

Motywacja

MIME , nowoczesny standard formatu poczty elektronicznej, zabrania kodowania nagłówków przy użyciu wartości bajtowych powyżej zakresu ASCII. Chociaż MIME umożliwia kodowanie treści wiadomości w różnych zestawach znaków (szerszych niż ASCII), podstawowa infrastruktura transmisji ( SMTP , główny standard przesyłania poczty e-mail) nadal nie jest gwarantowana jako 8-bitowa czysta . Dlatego w przypadku wątpliwości należy zastosować nietrywialne kodowanie przesyłania treści. Niestety base64 ma tę wadę, że nawet znaki US-ASCII stają się nieczytelne w klientach innych niż MIME. Z drugiej strony, UTF-8 w połączeniu z wydrukowanym w cudzysłowie daje bardzo nieefektywny format, wymagający 6-9 bajtów dla znaków spoza ASCII z BMP i 12 bajtów dla znaków spoza BMP.

Pod warunkiem, że podczas kodowania przestrzegane są pewne zasady, UTF-7 można wysłać pocztą e-mail bez użycia podstawowego kodowania transferu MIME , ale nadal musi być wyraźnie zidentyfikowany jako zestaw znaków tekstowych. Ponadto, jeśli jest używany w nagłówkach wiadomości e-mail, takich jak „Temat:”, UTF-7 musi być zawarty w słowach zakodowanych w MIME identyfikujących zestaw znaków. Ponieważ zakodowane słowa wymuszają użycie cytowanego-drukowalnego lub base64 , UTF-7 został zaprojektowany tak, aby uniknąć używania znaku = jako znaku ucieczki, aby uniknąć podwójnej ucieczki w połączeniu z cytowanym-drukowalnym (lub jego wariantem, RFC 2047/1522 Kodowanie ?Q? nagłówków).

UTF-7 na ogół nie jest używany jako natywna reprezentacja w aplikacjach, ponieważ jest bardzo niewygodny w przetwarzaniu. Pomimo przewagi rozmiarowej nad kombinacją UTF-8 z cytowanym drukiem lub base64, nieistniejące już Internet Mail Consortium odradzało jego używanie.

Wprowadzono również 8BITMIME , co zmniejsza potrzebę kodowania treści wiadomości w formacie 7-bitowym.

Zmodyfikowana forma UTF-7 (czasami nazywana „mUTF-7”) jest obecnie używana w protokole pobierania poczty e-mail IMAP dla nazw skrzynek pocztowych.

Opis

UTF-7 został po raz pierwszy zaproponowany jako protokół eksperymentalny w RFC 1642, A Mail-Safe Transformation Format of Unicode . Ten dokument RFC stał się przestarzały przez RFC 2152, informacyjny dokument RFC, który nigdy nie stał się standardem. Jak wyraźnie stwierdza RFC 2152, RFC „nie określa żadnego rodzaju standardu internetowego”. Mimo to RFC 2152 jest cytowany jako definicja UTF-7 na liście zestawów znaków IANA. Ani UTF-7 nie jest standardem Unicode. Standard Unicode 5.0 wymienia tylko UTF-8, UTF-16 i UTF-32. Istnieje również zmodyfikowana wersja, określona w RFC 2060, która jest czasami określana jako UTF-7.

Niektóre znaki mogą być reprezentowane bezpośrednio jako pojedyncze bajty ASCII. Pierwsza grupa znana jest jako „znaki bezpośrednie” i zawiera 62 znaki alfanumeryczne i 9 symboli: ' ( ) , - . / : ?. Bezpośrednie postacie można bezpiecznie włączyć dosłownie. Druga główna grupa, znana jako „opcjonalne znaki bezpośrednie”, zawiera wszystkie inne drukowalne znaki z zakresu U+ 0020 –U+007E z wyjątkiem ~ \ +spacji (znaki \i ~są wykluczone z powodu przedefiniowania w „wariantach ASCII”, takich jak JIS- rzymski ). Używanie opcjonalnych znaków bezpośrednich zmniejsza rozmiar i zwiększa czytelność dla ludzi, ale także zwiększa ryzyko złamania przez takie rzeczy, jak źle zaprojektowane bramy pocztowe i może wymagać dodatkowego ucieczki, gdy są używane w zakodowanych słowach w polach nagłówka.

Spacja, tabulator, powrót karetki i przesunięcie wiersza mogą być również reprezentowane bezpośrednio jako pojedyncze bajty ASCII. Jeśli jednak zakodowany tekst ma być używany w wiadomości e-mail, należy zadbać o to, aby znaki te były używane w sposób, który nie wymaga dalszego kodowania przesyłania treści, aby było odpowiednie dla wiadomości e-mail. Znak plus ( +) może być zakodowany jako +-.

Pozostałe znaki muszą być zakodowane w UTF-16 (stąd U+10000 i wyższe będą zakodowane na dwa surogaty), a następnie w zmodyfikowanym Base64 . Początek tych bloków zmodyfikowanego kodowania Base64 UTF-16 jest oznaczony +znakiem. Koniec jest oznaczony dowolnym znakiem spoza zmodyfikowanego zestawu Base64. Jeśli znak po zmodyfikowanym Base64 to -(ASCII myślnik-minus ), to jest on zużywany przez dekoder i dekodowanie jest wznawiane od następnego znaku. W przeciwnym razie dekodowanie zostanie wznowione ze znakiem następującym po base64.

Przykłady

  • Hello, World!” jest zakodowany jako „ Hello, World+ACE-
  • 1 + 1 = 2” jest zakodowany jako „ 1 +- 1 +AD0- 2
  • £1” jest zakodowane jako „ +AKM-1”. Punkt kodowy Unicode dla znaku funta to U+00A3, który przekształca się w zmodyfikowany Base64, jak w poniższej tabeli. Pozostały dwa bity, które są dopełniane do 0.
Cyfra szesnastkowa 0 0 A 3  
Wzór bitowy 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 1 0 0
Indeks 0 10 12
Kodowanie Base64 A K m

Algorytm kodowania i dekodowania

Kodowanie

Po pierwsze, koder musi zdecydować, które znaki mają być reprezentowane bezpośrednio w postaci ASCII, które +muszą zostać zmienione jako +-, a które umieścić w blokach znaków Unicode. Prosty koder może kodować wszystkie znaki, które uważa za bezpieczne do bezpośredniego kodowania. Jednak koszt zakończenia sekwencji Unicode, wyprowadzenia pojedynczego znaku bezpośrednio w ASCII, a następnie rozpoczęcia kolejnej sekwencji Unicode wynosi od 3 do 3.+23 bajty. To więcej niż 2+23 bajty potrzebne do reprezentowania znaku jako części sekwencji Unicode. Każda sekwencja Unicode musi być zakodowana przy użyciu poniższej procedury, a następnie otoczona odpowiednimi ogranicznikami.

Na przykładzie sekwencji znaków £† (U+00A3 U+2020):

  1. Wyraź numery Unicode postaci (UTF-16) w Binary:
  2. Połącz sekwencje binarne:
    0000 0000 1010 0011 i 0010 0000 0010 0000 → 0000 0000 1010 0011 0010 0000 0010 0000
  3. Przegrupuj binarny w grupy po sześć bitów, zaczynając od lewej:
    0000 0000 1010 0011 0010 0000 0010 0000 → 000000 001010 001100 100000 001000 00
  4. Jeśli ostatnia grupa ma mniej niż sześć bitów, dodaj końcowe zera:
    000000 001010 001100 100000 001000 00 → 000000 001010 001100 100000 001000 000000
  5. Zastąp każdą grupę sześciu bitów odpowiednim kodem Base64:
    000000 001010 001100 100000 001000 000000 → AKMgIA

Rozszyfrowanie

Najpierw zakodowane dane muszą być rozdzielone na kawałki zwykłego tekstu ASCII (w tym + es, po którym następuje myślnik) i niepuste bloki Unicode, jak wspomniano w sekcji opisu. Po wykonaniu tej czynności każdy blok Unicode musi zostać zdekodowany za pomocą następującej procedury (używając wyniku powyższego przykładu kodowania jako naszego przykładu)

  1. Wyraź każdy kod Base64 jako sekwencję bitową, którą reprezentuje:
    AKMgIA → 000000 001010 001100 100000 001000 000000
  2. Przegrupuj binarny w grupy szesnastu bitów, zaczynając od lewej:
    000000 001010 001100 100000 001000 000000 → 0000000010100011 0010000000100000 0000
  3. Jeśli na końcu znajduje się niepełna grupa zawierająca same zera, odrzuć ją (jeśli niekompletna grupa zawiera jedynki, kod jest nieprawidłowy):
    0000000010100011 0010000000100000
  4. Każda grupa 16 bitów jest numerem Unicode znaku (UTF-16) i może być wyrażona w innych formach:
    0000 0000 1010 0011 ≡ 0x00A3 ≡ 163 10

Oznaczenie kolejności bajtów

Znacznik kolejności bajtów (BOM) to opcjonalna specjalna sekwencja bajtów na samym początku strumienia lub pliku, która nie będąc samymi danymi, wskazuje kodowanie używane dla danych, które następują po nim; może być używany w przypadku braku metadanych oznaczających kodowanie. Dla danego schematu kodowania jest to reprezentacja tego schematu punktu kodowego Unicode U+FEFF.

Chociaż zazwyczaj jest to pojedyncza, ustalona sekwencja bajtów, w UTF-7 mogą pojawić się cztery odmiany, ponieważ ostatnie 2 bity czwartego bajtu kodowania UTF-7 U+FEFFnależą do następującego znaku, co daje 4 możliwe wzorce bitowe, a zatem 4 różne możliwe bajty na czwartej pozycji. Zobacz wpis UTF-7 w tabeli znaków kolejności bajtów Unicode .

Bezpieczeństwo

UTF-7 pozwala na wiele reprezentacji tego samego ciągu źródłowego. W szczególności znaki ASCII mogą być reprezentowane jako część bloków Unicode. W związku z tym, jeśli standardowe procesy kodowania lub walidacji oparte na ASCII są używane na ciągach, które mogą być później interpretowane jako UTF-7, to bloki Unicode mogą zostać użyte do przesunięcia złośliwych ciągów obok nich. Aby złagodzić ten problem, systemy powinny wykonać dekodowanie przed walidacją i powinny unikać prób automatycznego wykrywania UTF-7.

Starsze wersje Internet Explorera mogą zostać nakłonione do zinterpretowania strony jako UTF-7. Może to być wykorzystywane do cross-site scripting ataku, co <i >znaków mogą być kodowane jako +ADw-i +AD4-UTF-7, które większość zatwierdzające przepuszczać jako zwykły tekst.

UTF-7 jest uważany za przestarzały, przynajmniej w przypadku oprogramowania Microsoft (.NET), ze ścieżkami kodu, które wcześniej wspierały go celowo zepsute (aby zapobiec problemom z bezpieczeństwem) w .NET 5, w 2020 roku.

Bibliografia

Zobacz też