Upiec mi trochę moji

26

Biorąc pod uwagę ciąg znaków, listę znaków, strumień bajtów, sekwencję… która jest zarówno poprawnym UTF-8, jak i prawidłowym Windows-1252 (większość języków prawdopodobnie będzie chciała wziąć normalny ciąg UTF-8), przekonwertuj go (to znaczy udawaj , że jest ) Windows-1252 do UTF-8 .

Przykład przejścia

Ciąg UTF-8
I            UTF-8
jest reprezentowany jako bajty.
49 20E2 99 A520 55 54 46 2D 38
Te wartości bajtów w tabeli Windows-1252 dają nam odpowiedniki Unicode,
49 20 E2 2122 A5 20 55 54 46 2D 38
które są renderowane jako
I ⥠UTF-8

Przykłady

£Â£

£Â£

£Â£

I ♥ UTF-8I ♥ UTF-8

árvíztűrő tükörfúrógépárvÃztűrÅ‘ tükörfúrógép

Adám
źródło
9
@ user202729 Zobacz link „konwersja”. To gra słów.
Erik the Outgolfer
5
Dla wygody: zestaw znaków Windows 1252 jest taki sam jak Unicode, z wyjątkiem 0x80..0x9F, w których znajdują się znaki € ‚ƒ„…†‡ˆ‰Š‹Œ Ž ‘’“”•–—˜™š›œ žŸ. (spacja = nieużywane)
user202729
3
@ user202729 Uh, nie jestem pewien, co chciałeś powiedzieć, ale nie jest to wcale bliskie prawdy. Unicode ma miliony znaków, Windows-1252 tylko 256.
David Conrad
1
@DavidConrad, „Unicode ma miliony znaków” jest przesadzone. Unicode definiuje 1114112 punktów kodowych. Z tego obecnie używanych jest 136 690 współrzędnych kodowych.
Wernfried Domscheit
1
@Wernfried chodzi o porównanie tego z 256-znakowym zestawem znaków.
David Conrad

Odpowiedzi:

23

bash, 14 bajtów

iconv -fCP1252

Wypróbuj online!

Klamka
źródło
głosowałem, ale jeśli się nie mylę, to zakłada, że ​​kodowanie systemowe to utf-8
GiM
19

Java 8, 72 66 36 25 bajtów

s->new String(s,"cp1252")

Wypróbuj online.

s->  // Method with byte-array (UTF-8 by default) as parameter and String return-type
  new String(s,"cp1252")
     //  Pretend this UTF-8 input is (and convert it to) Windows-1252,
     //  and return it as UTF-8 String (by default) as well

cp1252jest pseudonimem dla Windows-1252. Ten alias cp1252to nazwa kanoniczna dla interfejsów API java.ioi java.lang, natomiast pełna nazwa Windows-1252to nazwa kanoniczna dla java.niointerfejsu API. Zobacz tutaj pełną listę obsługiwanych kodowań Java , w których zawsze chcielibyśmy używać najkrótszego z nich do kodowania.

Kevin Cruijssen
źródło
13
Zwycięski kod golfowy Java‽ To nie może być prawda.
Adám
1
@ Adám Hehe, jestem również mile zaskoczony, widząc te wszystkie dłuższe odpowiedzi. ;) Ale jestem pewien, że Jelly, 05AB1E itp. Wkrótce mnie pobiją.
Kevin Cruijssen
1
Wątpię w to. Prawdopodobnie nie mają wbudowanych tabel translacji. Dyalog APL robi…
Adám
„Nazwa kanoniczna java.niointerfejsu API”: P
tylko ASCII,
8

R 3.5.0 lub wyższy, 32 20 bajtów

scan(,"",e="latin1")

Wypróbuj online!

Dziwnie krótki na wyzwanie w R ... dzięki JayCe za grę w golfa jeszcze 12 bajtów!

scanopcjonalnie przyjmuje encodingargument, aby ustawić kodowanie ciągu wejściowego. latin1odpowiada, zgodnie z dokumentacjąEncoding

Istnieje pewna dwuznaczność co do tego, co należy rozumieć przez ustawienia regionalne „Latin-1”, ponieważ niektóre systemy operacyjne (zwłaszcza Windows) używają pozycji znaków używanych do znaków kontrolnych w zestawie znaków ISO 8859-1. Sposób interpretacji takich znaków zależy od systemu, ale od wersji 3.5.0 są one, jeśli to możliwe, interpretowane zgodnie ze stroną kodową Windows 1252 (którą Microsoft nazywa „Windows Latin 1 (ANSI)”) podczas konwersji na np. UTF-8.

Giuseppe
źródło
3
Połączyłem się z linkiem do dokumentacji Encoding... i dowiedziałem się, że scanma również encodingargument O_O ... 20 bajtów
JayCe
@JayCe whoda thunk it! Bardzo dobrze!
Giuseppe
6

Python 2 , 40 38 bajtów

-2 bajty dzięki Erikowi Outgolfer .

lambda s:s.decode('1252').encode('u8')

Wypróbuj online!

u8 to pseudonim utf-8.

ovs
źródło
Być może mógłbyś trochę „oszukać” za pomocą tego: input().decode(...).encode(...):) również myślę, że możesz być w stanie użyć kodowania konsoli Windows, jeśli jest w PowerShell (ale nie jestem tego pewien).
KeyWeeUsr
@KeyWeeUsr problem z twoją sugestią polega na tym, że tak naprawdę nic nie wyświetla, w przeciwieństwie do odpowiedzi, którą podałeś. R generuje wartość gołego wyrażenia, podczas gdy nie.
ovs
4

Python 3 , 38 36 34 bajtów

lambda s:s.encode().decode('1252')

Wypróbuj online!

Uwaga: po uruchomieniu funkcji użyłem odpowiedzi ovhon python2, aby dowiedzieć się o polach nagłówka i stopki dla tio, więc nagłówek i stopka są takie same

edit: Trochę go skróciłem dzięki domyślnemu python3 dla utf8 i wskazówce z przesłania ovsa :)

GammaGames
źródło
3

JavaScript, 64 bajty

x=>new TextDecoder('cp1252').decode(new TextEncoder().encode(x))

Nawet dłużej niż odpowiedź Java. Taki smutny. :(

tsh
źródło
3

C #, 81 bajtów

using e=System.Text.Encoding;s=>e.GetEncoding(1252).GetString(e.UTF8.GetBytes(s))

Wypróbuj online!

Dzięki Schmalls za 3 bajty

Mego
źródło
Czy da using e=System.Text.Encoding;s=>e.GetEncoding(1252).GetString(e.UTF8.GetBytes(s))się zmniejszyć do 81?
Schmalls
@ Schmalls Wygląda na to, dziękuję!
Mego
2

180 bajtów, kod maszynowy (16-bit x86)

Zauważyłem, że większość odpowiedzi używa wbudowanego kodowania / dekodowania (co moim zdaniem jest w porządku), ale pomyślałem, że będę kontynuować moją 16-bitową misję .

Podobnie jak w poprzednich, zostało to zrobione bez kompilatora przy użyciu głównie heksitora HT i heksplorera ICY .

00000000: eb40 ac20 0000 1a20 9201 1e20 2620 2020  .@. ... ... &                     
00000010: 2120 c602 3020 6001 3920 5201 0000 7d01  ! ..0 `.9 R...}.                  
00000020: 0000 0000 1820 1920 1c20 1d20 2220 1320  ..... . . . " .                   
00000030: 1420 dc02 2221 6101 3a20 5301 0000 7e01  . .."!a.: S...~.                  
00000040: 7801 89f7 4646 89fa 89d9 4143 4bb4 3fcd  x...FF....ACK.?.                  
00000050: 2185 c074 288a 053c 8073 05e8 1700 ebec  !..t(..<.s......                  
00000060: 3ca0 721a d440 0d80 c050 86c4 e806 0058  <[email protected]                  
00000070: e802 00eb d7b4 4088 05b3 01cd 21c3 2c80  ......@.....!.,.                  
00000080: d0e0 89c3 8b00 89cb 85c0 74c0 3dff 0773  ..........t.=..s                  
00000090: 08c1 c002 c0e8 02eb cd50 c1e8 0c0c e0e8  .........P......                  
000000a0: d3ff 5825 ff0f c1c0 02c0 e802 0d80 8050  ..X%...........P                  
000000b0: 86c4 ebb8                                ....                              

bake.com <input.txt> out.dat

Sekcja

Wdrożenie jest dość proste, chociaż nie zastanawiałem się nad tym, aby wypłynąć z góry, więc jest tam NIEKTÓRE spaghetti.

Zmiksuję trochę zamówienie, aby ułatwić śledzenie ...

0000 eb40               jmp         0x42

Pomiń tabelę, która mapuje znaki> = 0x80 <0xa0, na kody Unicode.

data db ACh,20h, 00h,00h, 1Ah,20h, ...

Nieprawidłowe są zakodowane jako 0, nie są odwzorowane na nic

0075 b440               mov         ah, 0x40   
0077 8805               mov         [di], al   
0079 b301               mov         bl, 0x1    
007b cd21               int         0x21       
007d c3                 ret                    

Funkcja pomocnicza użyta do wydrukowania znaku albędzie wywoływana kilka razy.

0042 89f7               mov         di, si     
0044 46                 inc         si         
0045 46                 inc         si         
0046 89fa               mov         dx, di     
0048 89d9               mov         cx, bx     
004a 41                 inc         cx         
004b 43                 inc         bx         

Przygotuj rejestry. Dane zostaną wczytane do 0x100, niech sipunkt w tabeli translacji powyżej.

004c 4b                 dec         bx         
004d b43f               mov         ah, 0x3f   
004f cd21               int         0x21       
0051 85c0               test        ax, ax     
0053 7428               jz          0x7d       

Odczytaj char ze standardowego wejścia, przeskocz do 0x7d, jeśli EOF.

Sidenote: To rzeczywiście jest niewielka (ale dość dobrze znana) trik, 0x7D zawiera ret, spowoduje to pop sp, spw punktach początku do końca odcinka, nie 00 00istnieje, a cs:0w DOS zawiera CD 20, co powoduje, że wniosek do wyjścia.

0055 8a05               mov         al, [di]   
0057 3c80               cmp         al, 0x80   
0059 7305               jnc         0x60       
005b e81700             call        0x75       
005e ebec               jmp         0x4c       

Jeśli char jest <0x80, po prostu wydrukuj go i przejdź do początku pętli (ponieważ funkcja pomocnika ustawia BX na 1 - standardowe wyjście, skoki przejdą do dec bx)

0060 3ca0               cmp         al, 0xa0   
0062 721a               jc          0x7e       
0064 d440               aam         0x40       
0066 0d80c0             or          ax, c080   
0069 50                 push        ax         
006a 86c4               xchg        ah, al     
006c e80600             call        0x75       
006f 58                 pop         ax         
0070 e80200             call        0x75       
0073 ebd7               jmp         0x4c       

Ta część dotyczy znaków> = 0xa0, dzieli kod ascii na „wysoki” dwa bity i „niski” 6 bitów i stosuje maskę utf-8 c080 dla dwóch bajtów, a następnie drukuje oba z nich

007e 2c80               sub         al, 0x80   
0080 d0e0               shl         al, 0x1    
0082 89c3               mov         bx, ax     
0084 8b00               mov         ax, [bx+si]
0086 89cb               mov         bx, cx     
0088 85c0               test        ax, ax     
008a 74c0               jz          0x4c       
008c 3dff07             cmp         ax, 07ff   
008f 7308               jnc         0x99       
0091 c1c002             rol         ax, 0x2    
0094 c0e802             shr         al, 0x2    
0097 ebcd               jmp         0x66       

Ta część dotyczy znaków> = 0x80 <0xa0, znajduje odpowiedni kod utf-8 w tabeli u góry, jeśli kod jest równy 0, po prostu przejdź do początku, jeśli jest poniżej 0x7ff (ergo: pasuje do dwóch bajtów UTF-8) , po prostu dostosuj wartość i ponownie użyj poprzedniego kodu o wartości 0x166.

0099 50                 push        ax         
009a c1e80c             shr         ax, 0xc    
009d 0ce0               or          al, e0     
009f e8d3ff             call        0x75       
00a2 58                 pop         ax         
00a3 25ff0f             and         ax, 0fff   
00a6 c1c002             rol         ax, 0x2    
00a9 c0e802             shr         al, 0x2    
00ac 0d8080             or          ax, 8080   
00af 50                 push        ax         
00b0 86c4               xchg        ah, al     
00b2 ebb8               jmp         0x6c       

Ostatnia część dotyczy kodów powyżej 0x7FF, upuszcza 12 bitów, stosuje 0xE0 (patrz opis kodowania UTF-8 w celach informacyjnych) i drukuje, dostosowuje 12 bitów i stosuje maskę 8080 i ponownie wykorzystuje część, która wyrzuca dwa znaki .

GiM
źródło
1

PHP + mbstring , 63 49 bajtów

<?=mb_convert_encoding($argv[1],'UTF8','CP1252');

Nie działa na TIO z powodu braku mbstring. Trzeci parametr zmusza mbstring do interpretacji ciągu jako zakodowanego w Windows-1252

-14 bajtów dzięki Ismaelowi Miguelowi

Sefa
źródło
<?=mb_convert_encoding($argv[1],'UTF8','CP1252');<- jeszcze krótszy!
Ismael Miguel
0

C (gcc) + libiconv, 119 117 bajtów

*f(s,t,u)void*s,*t,*u;{long i=strlen(s),j=i*4;u=t=malloc(j);iconv(iconv_open("UTF8","CP1252"),&s,&i,&u,&j);return t;}

Wypróbuj online!

ErikF
źródło
W tym przypadku powinieneś zmienić język na „C (gcc) + libiconv”
tylko ASCII
103 bajty
pułapkat