Asse-me um pouco de moji

26

Dada uma sequência de caracteres, lista de caracteres, fluxo de bytes, sequência ... que é UTF-8 válido e Windows-1252 válido (a maioria dos idiomas provavelmente desejará usar uma sequência UTF-8 normal), converta-a (isto é, finja que é ) Windows-1252 para UTF-8 .

Exemplo percorrido

A sequência UTF-8
I            UTF-8
é representada como os bytes
49 20E2 99 A520 55 54 46 2D 38
desses valores de bytes na tabela Windows-1252 nos fornecem os equivalentes Unicode
49 20 E2 2122 A5 20 55 54 46 2D 38
que são renderizados como
I ⥠UTF-8

Exemplos

£Â£

£Â£

£Â£

I ♥ UTF-8I ♥ UTF-8

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

Adão
fonte
9
@ user202729 Consulte o link "convertê-lo". É um trocadilho.
Erik the Outgolfer
5
Por conveniência: O conjunto de caracteres do Windows 1252 é igual ao Unicode, exceto em 0x80..0x9F, onde estão os caracteres € ‚ƒ„…†‡ˆ‰Š‹Œ Ž ‘’“”•–—˜™š›œ žŸ. (space = unused)
user202729
3
@ user202729 Uh, não sei ao certo o que você estava tentando dizer, mas isso não é remotamente próximo de ser verdade. Unicode tem milhões de caracteres, o Windows-1252 única 256.
David Conrad
1
@ DavidConrad, "Unicode tem milhões de caracteres" é exagerado. O Unicode define 1.114.112 pontos de código. Desses, 136.690 pontos de código são usados ​​atualmente.
Wernfried Domscheit
1
@Wernfried, o ponto é comparar isso com um conjunto de caracteres de 256 caracteres.
David Conrad

Respostas:

23

bash, 14 bytes

iconv -fCP1252

Experimente online!

Maçaneta da porta
fonte
votado, mas se não me engano, isso pressupõe que a codificação do sistema seja utf-8
GiM
19

Java 8, 72 66 36 25 bytes

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

Experimente 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

cp1252é um alias para Windows-1252. Esse alias cp1252é o nome canônico das APIs java.ioe java.lang, enquanto o nome completo Windows-1252é o nome canônico da java.nioAPI. Veja aqui uma lista completa de codificações Java suportadas , onde sempre queremos usar o menor dos dois para codegolfing.

Kevin Cruijssen
fonte
13
Código vencedor do Java golf‽ Isso não pode estar certo.
Adám
1
@ Adám Hehe, estou realmente agradavelmente surpreso ao ver todas essas respostas mais longas. ;) Mas tenho certeza de que Jelly, 05AB1E, etc. me vencerá em breve.
Kevin Cruijssen
1
Eu duvido disso. Eles provavelmente não possuem tabelas de conversão integradas. Dyalog APL does though…
Adám 21/06
"Nome canonial para a java.nioAPI": P
somente ASCII
8

R 3.5.0 ou superior, 32 20 bytes

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

Experimente online!

Estranhamente curto para um desafio de em R ... obrigado a JayCe por jogar mais 12 bytes!

scanopcionalmente, utiliza um encodingargumento para definir a codificação da sequência de entrada. latin1corresponde, de acordo com a documentação doEncoding

Existe alguma ambiguidade quanto ao significado de um código de idioma 'Latin-1', pois alguns sistemas operacionais (principalmente o Windows) usam posições de caracteres usadas para caracteres de controle no conjunto de caracteres ISO 8859-1. Como esses caracteres são interpretados depende do sistema, mas a partir do R 3.5.0, eles são, se possível, interpretados conforme a página de código 1252 do Windows (que a Microsoft chama de 'Windows Latin 1 (ANSI)') ao converter para, por exemplo, UTF-8.

Giuseppe
fonte
3
Eu segui o link para a documentação de Encoding... e soube que scantambém tem um encodingargumento O_O ... 20 bytes
Jayce
@JayCe whoda thunk it! Muito agradável!
Giuseppe
6

Python 2 , 40 38 bytes

-2 bytes graças a Erik, o Outgolfer .

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

Experimente online!

u8 é um apelido para utf-8.

ovs
fonte
Talvez você possa "trapacear" um pouco com isso: input().decode(...).encode(...):) também acho que você poderá usar alguma codificação do console do Windows se estiver no PowerShell (mas não tenho muita certeza disso).
KeyWeeUsr
@KeyWeeUsr O problema com sua sugestão é que, na verdade, ela não produz nada, em oposição à resposta que você vinculou. R produz o valor da expressão nua, enquanto não produz.
ovs 21/06
4

Python 3 , 38 36 34 bytes

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

Experimente online!

note: Depois de ter uma função em funcionamento, usei a resposta python2 da ovs para aprender sobre os campos de cabeçalho e rodapé do tio, para que o cabeçalho e o rodapé sejam os mesmos

edit: Aparado um pouco graças ao python3 por padrão em utf8 e uma dica da submissão do ovs :)

GammaGames
fonte
3

JavaScript, 64 bytes

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

Ainda mais do que a resposta Java. Tão triste. :(

tsh
fonte
3

C #, 81 bytes

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

Experimente online!

Agradecimentos a Schmalls por 3 bytes

Mego
fonte
Pode ser using e=System.Text.Encoding;s=>e.GetEncoding(1252).GetString(e.UTF8.GetBytes(s))baixá-lo para 81?
Schmalls
@Schmalls Parece que sim, obrigado!
Mego #
2

180 bytes, código de máquina (x86 de 16 bits)

Percebi que a maioria das respostas usa codificação / decodificação embutida (que eu acredito que esteja perfeitamente bem), mas pensei em continuar minha busca de 16 bits .

Como nos anteriores, isso foi feito sem o compilador, usando principalmente o hexeditor HT e o hexplorer da 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

Dissecação

A implementação é bem direta, embora eu não tenha pensado muito em fluir antecipadamente, então há ALGUM espaguete por lá.

Vou misturar um pouco a ordem, para facilitar o acompanhamento ...

0000 eb40               jmp         0x42

Pule a tabela que mapeia caracteres> = 0x80 <0xa0, para códigos unicode.

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

Os inválidos são codificados como 0, não são mapeados para nada

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

A função auxiliar usada para imprimir char alserá chamada algumas vezes.

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         

Prepare registros. Os dados serão lidos em 0x100, vamos siapontar para a tabela de conversão acima.

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

Leia char de stdin, pule para 0x7d se EOF.

Nota: Este é realmente um pequeno (mas bastante conhecido) truque, 0x7d contém ret, isso fará com que pop sp, spnos pontos de início ao final de um segmento, 00 00exista, e cs:0no DOS contenha CD 20, o que faz com que o aplicativo saia.

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

Se char for <0x80, imprima-o e vá para o início do loop (porque a função helper está configurando BX como 1 - stdout, os saltos irão para 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       

Esta parte trata de chars> = 0xa0, divide o código ascii em "alto" dois bits e "baixo" 6 bits e aplica a máscara utf-8 c080 para dois bytes, depois imprime os dois

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       

Esta parte lida com chars> = 0x80 <0xa0, encontra o código utf-8 adequado na tabela na parte superior, se o código for igual a 0, pule para o início, se estiver abaixo de 0x7ff (ergo: cabe em dois bytes UTF-8) , basta ajustar o valor e reutilizar o código anterior em 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       

A parte final, lida com códigos acima de 0x7FF, reduz 12 bits baixos, aplica 0xE0 (consulte a descrição da codificação UTF-8 para referência) e imprime, ajusta 12 bits inferiores e aplica a máscara 8080 e reutiliza novamente a parte que cospe dois caracteres .

GiM
fonte
1

PHP + mbstring , 63 49 bytes

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

Não funciona no TIO devido à falta de mbstring. O terceiro parâmetro força o mbstring a interpretar a sequência como codificada em Windows-1252

-14 bytes graças a Ismael Miguel

Sefa
fonte
<?=mb_convert_encoding($argv[1],'UTF8','CP1252');<- ainda mais curto!
Ismael Miguel
0

C (gcc) + libiconv, 119 117 bytes

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

Experimente online!

ErikF
fonte
Você deve alterar o idioma para "C (gcc) + libiconv" neste caso
somente ASCII
103 bytes
ceilingcat