Panggang aku moji

26

Diberikan string, daftar karakter, aliran byte, urutan ... yang keduanya UTF-8 dan Windows-1252 yang valid (sebagian besar bahasa mungkin ingin mengambil string UTF-8 yang normal), mengubahnya dari (yaitu, berpura - pura adalah ) Windows-1252 ke UTF-8 .

Contoh walked-through

String UTF-8
I            UTF-8
direpresentasikan sebagai
49 20E2 99 A520 55 54 46 2D 38
byte nilai-nilai byte ini dalam tabel Windows-1252 memberi kita ekuivalen Unicode
49 20 E2 2122 A5 20 55 54 46 2D 38
yang dirender sebagai
I ⥠UTF-8

Contohnya

£Â£

£Â£

£Â£

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
sumber
9
@ user202729 Lihat tautan "convert it". Ini adalah permainan kata-kata.
Erik the Outgolfer
5
Untuk kenyamanan: Kumpulan karakter Windows 1252 sama dengan Unicode, kecuali dalam 0x80..0x9F, di mana karakter berada € ‚ƒ„…†‡ˆ‰Š‹Œ Ž ‘’“”•–—˜™š›œ žŸ. (spasi = tidak digunakan)
user202729
3
@ user202729 Eh, saya tidak yakin apa yang Anda katakan, tapi itu tidak jauh dari kenyataan. Unicode memiliki jutaan karakter, Windows-1252 hanya 256.
David Conrad
1
@ Davidvidon, "Unicode memiliki jutaan karakter" dilebih-lebihkan. Unicode mendefinisikan 1.114.112 codepoint. Dari 136.690 codepoint saat ini digunakan.
Wernfried Domscheit
1
@Wernfried intinya adalah membandingkannya dengan charset 256 karakter.
David Conrad

Jawaban:

23

bash, 14 byte

iconv -fCP1252

Cobalah online!

Gagang pintu
sumber
terbalik, tetapi jika saya tidak salah, itu mengasumsikan, bahwa pengkodean sistem utf-8
GiM
19

Java 8, 72 66 36 25 byte

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

Cobalah 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

cp1252adalah alias untuk Windows-1252. Alias ​​ini cp1252adalah Nama Canonical untuk java.iodan java.langAPI, sedangkan nama lengkap Windows-1252adalah Nama Canonical untuk java.nioAPI. Lihat di sini untuk daftar lengkap penyandian Java yang didukung , tempat kami selalu ingin menggunakan yang terpendek dari keduanya untuk codegolfing.

Kevin Cruijssen
sumber
13
Java memenangkan kode golf‽ Itu tidak mungkin benar.
Adám
1
@ Adám Hehe, saya sebenarnya sangat terkejut juga melihat semua jawaban yang lebih panjang ini. ;) Tapi saya cukup yakin Jelly, 05AB1E, dll. Akan mengalahkan saya segera.
Kevin Cruijssen
1
Saya meragukan itu. Mereka mungkin tidak memiliki tabel terjemahan bawaan. Namun Dyalog APL…
Adám
"Nama Canonial untuk java.nioAPI": P
ASCII-satunya
8

R 3.5.0 atau lebih tinggi, 32 20 byte

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

Cobalah online!

Anehnya pendek untuk tantangan di R ... terima kasih kepada JayCe untuk bermain golf 12 byte lebih banyak!

scanopsional mengambil encodingargumen untuk mengatur pengkodean string input. latin1sesuai dengan, sesuai dengan dokumentasiEncoding

Ada beberapa ambiguitas mengenai apa yang dimaksud dengan lokal 'Latin-1', karena beberapa OS (terutama Windows) memanfaatkan posisi karakter yang digunakan untuk karakter kontrol dalam set karakter ISO 8859-1. Bagaimana karakter tersebut diartikan tergantung pada sistem tetapi dari R 3.5.0 mereka jika mungkin diinterpretasikan sesuai dengan codepage Windows 1252 (yang oleh Microsoft disebut 'Windows Latin 1 (ANSI)') ketika mengkonversi ke misalnya UTF-8.

Giuseppe
sumber
3
Saya mengikuti tautan ke dokumentasi Encoding... dan mengetahui bahwa ada scanjuga encodingargumen O_O ... 20 byte
JayCe
@JayCe whoda melemparkannya! Sangat bagus!
Giuseppe
6

Python 2 , 40 38 byte

-2 byte terima kasih kepada Erik the Outgolfer .

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

Cobalah online!

u8 adalah alias untuk utf-8.

ovs
sumber
Mungkin Anda bisa "menipu" sedikit dengan ini: input().decode(...).encode(...):) juga saya pikir Anda mungkin dapat menggunakan beberapa pengkodean konsol windows jika dalam PowerShell (tapi saya benar-benar tidak yakin tentang ini).
KeyWeeUsr
@KeyWeeUsr masalah dengan saran Anda adalah bahwa sebenarnya tidak menghasilkan apa-apa, yang bertentangan dengan jawaban yang Anda tautkan. R tidak menampilkan nilai ekspresi telanjang sementara tidak.
Ov
4

Python 3 , 38 36 34 byte

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

Cobalah online!

catatan: Setelah saya memiliki fungsi kerja saya menggunakan jawaban python2 jawaban ovs untuk belajar tentang header dan footer field untuk tio, jadi header dan footer adalah sama

sunting: Memangkasnya sedikit berkat python3 default ke utf8 dan tip dari pengiriman ovs :)

GammaGames
sumber
3

JavaScript, 64 byte

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

Bahkan lebih lama dari jawaban Java. Sangat sedih. :(

tsh
sumber
3

C #, 81 byte

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

Cobalah online!

Terima kasih kepada Schmalls untuk 3 byte

Mego
sumber
Bisakah itu menjadi using e=System.Text.Encoding;s=>e.GetEncoding(1252).GetString(e.UTF8.GetBytes(s))81?
Schmalls
@Schmalls Sepertinya ya, terima kasih!
Mego
2

180 byte, kode mesin (16-bit x86)

Saya perhatikan sebagian besar jawaban menggunakan builtin encode / decode (yang saya percaya baik-baik saja), tapi saya pikir saya akan melanjutkan pencarian 16-bit saya .

Seperti yang sebelumnya, ini dilakukan tanpa kompiler menggunakan HT hexeditor kebanyakan dan hexplorer 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

Pembedahan

Implementasinya cukup mudah, meskipun saya belum banyak berpikir untuk mengalir di muka sehingga ada beberapa spaghetti di sana.

Saya akan mencampur pesanan sedikit, untuk membuatnya lebih mudah diikuti ...

0000 eb40               jmp         0x42

Lewati tabel yang memetakan karakter> = 0x80 <0xa0, ke kode unicode.

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

Yang tidak valid dikodekan sebagai 0, mereka tidak dipetakan ke apa pun

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

Fungsi pembantu yang digunakan untuk mencetak char al, akan dipanggil beberapa kali.

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         

Siapkan register. Data akan dibaca menjadi 0x100, mari kita situnjukkan ke tabel terjemahan di atas.

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

Baca char dari stdin, lompat ke 0x7d jika EOF.

Sidenote: Ini sebenarnya adalah trik kecil (tapi cukup terkenal), berisi 0x7d ret, ini akan menyebabkan pop sp, sppada titik awal hingga akhir segmen, ada di 00 00sana, dan cs:0dalam DOS berisi CD 20, yang menyebabkan aplikasi keluar.

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

Jika char <0x80, cetak saja, dan lanjutkan ke awal loop (karena fungsi helper mengatur BX ke 1 - stdout, lompatan akan ke 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       

Bagian ini membahas karakter chars> = 0xa0, membagi kode ascii menjadi "tinggi" dua bit dan "rendah" 6 bit dan menerapkan utf-8 mask c080 untuk dua byte, lalu mencetak keduanya

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       

Bagian ini berkaitan dengan karakter> = 0x80 <0xa0, ia menemukan kode utf-8 yang sesuai pada tabel di atas, jika kode sama dengan 0, lompati saja ke awal, jika di bawah 0x7ff (ergo: cocok untuk dua byte UTF-8 byte) , sesuaikan nilainya dan gunakan kembali kode sebelumnya pada 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       

Bagian terakhir, berurusan dengan kode yang berada di atas 0x7FF, drop rendah 12 bit, terapkan 0xE0 (lihat deskripsi penyandian UTF-8 untuk referensi) dan cetaklah, sesuaikan 12 bit yang lebih rendah dan terapkan 8080 mask dan gunakan kembali bagian yang mengeluarkan dua karakter .

GiM
sumber
1

PHP + mbstring , 63 49 byte

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

Ini tidak berfungsi pada TIO karena kurangnya mbstring. Parameter ketiga memaksa mbstring untuk menafsirkan string sebagai Windows-1252 dikodekan

-14 byte terima kasih kepada Ismael Miguel

Sefa
sumber
<?=mb_convert_encoding($argv[1],'UTF8','CP1252');<- bahkan lebih pendek!
Ismael Miguel
0

C (gcc) + libiconv, 119 117 byte

*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;}

Cobalah online!

ErikF
sumber
Anda harus mengubah bahasa menjadi "C (gcc) + libiconv" dalam kasus ini
ASCII
103 byte
ceilingcat