UTF-8 jest stosunkowo prostym sposobem kodowania punktów kodowych Unicode w formacie o zmiennej szerokości, dzięki czemu nie łatwo pomylić kodu, który nie jest świadomy Unicode.
Omówienie UTF-8
- Bajty w zakresie 1-0x7F włącznie, zwykle są prawidłowe
- Bajty ze wzorem bitowym
10XX XXXX
są uważane za bajty kontynuacyjne, przy czym sześć najmniej znaczących bitów jest używanych do kodowania części punktu kodowego. Nie mogą się pojawiać, chyba że oczekują ich poprzednie bajty. - Bajty ze wzorem
110X XXXX
oczekują później jednego bajtu kontynuacji - Bajty ze wzorcem
1110 XXXX
oczekują później dwóch bajtów kontynuacji - Bajty ze wzorcem
1111 0XXX
oczekują później trzech bajtów kontynuacji - Wszystkie pozostałe bajty są nieprawidłowe i nie powinny pojawiać się nigdzie w strumieniu UTF-8. Teoretycznie klastry 5, 6 i 7 bajtów są możliwe, ale nie będą dozwolone na potrzeby tego wyzwania.
Zbyt długie kodowanie
UTF-8 wymaga również, aby kod był reprezentowany przez minimalną liczbę bajtów. Każda sekwencja bajtów, która może być reprezentowana przez mniej bajtów, jest niepoprawna. Zmodyfikowany UTF-8 dodaje jeden wyjątek dla znaków zerowych (U + 0000), które powinny być reprezentowane jako C0 80
(reprezentacja szesnastkowa), i zamiast tego uniemożliwia pojawienie się pustych bajtów w dowolnym miejscu w strumieniu. (Dzięki temu jest kompatybilny z ciągami zakończonymi znakiem null)
Wyzwanie
Masz stworzyć program, który, gdy otrzyma ciąg bajtów, określi, czy ten ciąg reprezentuje prawidłową Zmodyfikowaną UTF-8 i zwróci prawdę, jeśli jest poprawna, lub wartość fałszowania w przeciwnym razie. Zauważ, że musisz sprawdzić, czy nie ma zbyt długiego kodowania i pustych bajtów (ponieważ jest to Zmodyfikowany UTF-8). Nie musisz dekodować wartości UTF-8.
Przykłady
41 42 43 ==> yes (all bytes are in the 0-0x7F range)
00 01 02 ==> no (there is a null byte in the stream)
80 7F 41 ==> no (there is a continuation byte without a starter byte)
D9 84 10 ==> yes (the correct number of continuation bytes follow a starter byte)
F0 81 82 41 ==> no (there are not enough continuation bytes after F0)
EF 8A A7 91 ==> no (too many continuation bytes)
E1 E1 01 ==> no (starter byte where a continuation byte is expected)
E0 80 87 ==> no (overlong encoding)
41 C0 80 ==> yes (null byte encoded with the only legal overlong encoding)
F8 42 43 ==> no (invalid byte 'F8')
Zasady
- Obowiązują standardowe zasady i luki
- Dane wejściowe i wyjściowe mogą być w dowolnym dogodnym formacie, o ile można odczytać wszystkie wartości z zakresu bajtów bez znaku (0–255).
- Może być konieczne użycie tablicy lub pliku zamiast łańcucha zakończonego znakiem null. Musisz być w stanie odczytać bajty zerowe.
- Najkrótszy kod wygrywa!
- Pamiętaj, że użycie wbudowanych narzędzi do dekodowania UTF-8 nie gwarantuje zgodności z podanymi tutaj wymaganiami. Może być konieczne obejście tego i utworzenie specjalnych przypadków.
EDYCJA: dodano premię za nieużywanie wbudowanych funkcji dekodujących UTF-8
EDYCJA 2: usunięto premię, ponieważ kwalifikowała się tylko odpowiedź Rdza i trudno jest zdefiniować.
źródło
Odpowiedzi:
Eliksir , 69 bajtów
Wypróbuj online!
Wykorzystuje wbudowaną funkcję sprawdzania poprawności ciągu. Pobiera dane wejściowe jako plik binarny Elixir.
źródło
APL (Dyalog Unicode) ,
4139 bajtów SBCSAnonimowa ukryta funkcja prefiksu. Bierze ciąg Unicode jako argument, w którym punkty kodowe znaków reprezentują bajty wejściowe.
Wypróbuj online!
'À\x80'⎕R⎕A
R EUmieãæC0 80
s z wielką A lphabet{
…}
Zastosuj następującą anonimową funkcję, gdzie argumentem jest⍵
:0::
jeśli wystąpi jakikolwiek błąd:0
zwróć zero⋄
próbować:⎕UCS⍵
przekonwertować ciąg na punkty kodowe'UTF-8'⎕UCS⍣2
interpretować jako bajty UTF-8 i konwertować wynikowy tekst z powrotem na bajty⌊/
najniższy bajt (zero, jeśli występuje bajt zerowy, dodatni, jeśli nie, „nieskończoność”, jeśli pusty ciąg)×
znak (zero, jeśli bajt null jest obecny, jeden, jeśli nie jest)źródło
D9 C0 80 84 C0 80 10
?C0 80
powoduje, że niepowiązane bajty sąsiadują ze sobą w prawidłowy sposób, chociaż są one niepoprawne, gdy są oddzielone? Edycja: Zaktualizowano, aby naprawić to bez kosztów bajtów.Python 2 ,
104102 bajtówWypróbuj online!
Dane wyjściowe za pośrednictwem kodu wyjścia
źródło
Rdza -
191 bajtów313 bajtówDla komentarza poniżej oryginału nie działał poprawnie. Nowa i ulepszona wersja. Żadne biblioteki nie są używane, ponieważ Potężna rdza nie potrzebuje ciebie i twoich bibliotek. Ten kod używa dopasowania wzorca z maszyną stanu. Przez bezwstydnie oderwanie spec UTF8 , po znalezieniu go poprzez odniesienie i dyskusji Jon Skeet , możemy skopiować spec prawie znaków dla charakterem do rdzy Meczu bloku wzór meczu. Na koniec dodajemy specjalne wymaganie Mutf8 Beefstera, aby C0 80 został uznany za ważny. Nie golfowany:
spróbuj na placu zabaw z rdzą
źródło