Converti una stringa di caratteri binari in equivalenti ASCII


27

Prendi una stringa di caratteri binari separati da uno spazio e convertila in una stringa ASCII.

Per esempio...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Converti in ...

Hello World

La stringa binaria verrà memorizzata in una variabile chiamata s.

Questa è una sfida di code-golf, quindi vince la soluzione più breve.


15
+1 per fare una sfida senza storia e altri fripperies, direttamente al punto
bebe

9
@bebe Fripper fantasiosi e fittizi formano metà del divertimento.
qwr,

Ciao. Immaginiamo che la tua tecnologia sia così avanzata da non supportare ASCII. Potrebbe essere convertito nella codifica dei caratteri nativi o dovrebbe convertire ASCII nella codifica dei caratteri nativi? Sto pensando ZX81qui.
Shaun Bebbers

Risposte:


10

Ruby, 36 32

s.split.map{|x|x.to_i(2).chr}*""

O 31

s.gsub(/\w+ ?/){$&.to_i(2).chr}

Ottimizzazioni grazie a Chron


1
È possibile sostituire .join""per *""salvare alcuni personaggi. Potresti anche farlo con gsub invece di split + map + join, qualcosa del tipo: s.gsub(/\w+ ?/){$&.to_i(2).chr}(31 caratteri).
Paul Prestidge,

2
s.gsub(/\d+./){$&.to_i(2).chr}funziona ed è di 30 caratteri, non ho idea del perché funzioni però. Non .dovrebbe corrispondere l'ultima volta ma lo fa.
addison

10

JavaScript (ES6) 49 55 56 64

s.replace(/\d+./g,x=>String.fromCharCode('0b'+x))

Modifica Accettazione del suggerimento di @bebe - grazie a
Edit2 Non sapevo del valore letterale numerico binario - grazie @kapep
Edit3 Wow 6 non 4 byte salvati grazie a @ETHproductions

Spiegazione come richiesto nei commenti

String.replace può accettare 2 argomenti:

  • espressione regolare /\d+./g: una o più cifre seguite da un carattere diverso: l'indicatore g specifica di cercare il motivo più di una volta
  • una funzione, qui specificata in formato freccia, in cui l'argomento (x) sarà la stringa trovata (la sequenza di cifre alla fine seguita da uno spazio) e il valore della funzione è ciò che viene sostituito (in questo caso, il singolo carattere da il codice).

Vale la pena notare che alla fine della stringa la regexp corrisponde alla sequenza di cifre senza uno spazio finale, in questo caso il punto corrisponde all'ultima cifra. Prova '123'.match (/ (\ d +) ./) per verificare.

(Ancora) uno dei pezzi più dettagliati di javascript di sempre ...
(L'assegnazione alle stringhe non viene conteggiata)

var s='1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100'
var x=
s.replace(/\d+./g,x=>String.fromCharCode('0b'+x))

console.log(x)


2
s.replace(/\d+./g,x=>String.fromCharCode(parseInt(x,2)))56
Bebe,

2
s.replace(/\d+./g,x=>String.fromCharCode(eval("0b"+x)))55
Kapex,

Puoi per favore spiegare cosa /\d+./g,x=>fa?
izlin,

1
@izlin Ho aggiunto qualche spiegazione alla risposta
edc65,

So che questa è una vecchia risposta, ma è possibile passare eval('0b'+x)a '0b'+x-0per salvare 4 byte.
ETHproductions

8

Bash + utility Linux comuni, 25 byte

dc<<<2i$s[Pz0\<m]dsmx|rev

spiegazione in cc

  • spingere 2 nello stack; pop e usare come input radix
  • spingere la stringa di input per impilare (tutti i valori contemporaneamente)
  • Definire la macro ricorsiva mper:
    • pop, quindi stampa il valore come ASCII
    • spingere la profondità dello stack per impilare
    • premere 0 per impilare
    • pop top 2 valori dello stack; confronta e chiama la mmacro se lo stack non è vuoto
  • duplicato parte superiore dello stack (definizione macro)
  • pop e salva macro per mregistrarti
  • pop ed esegui macro

Poiché prima spingiamo l'intera stringa binaria nello stack, quando popiamo ciascun valore, finiamo con la stringa invertita. Quindi usiamo l' revutilità per correggerlo.

Esempio di utilizzo:

$ s="1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
$ dc<<<2i$s[Pz0\<m]dsmx|rev
Hello World
$ 

7

PowerShell, 49

-join(-split$s|%{[char][convert]::toint32($_,2)})

EDIT: Non ho visto l'altra risposta PowerShell. Ma c'è essenzialmente solo un modo per risolverlo.


7

C - 57 43 38/31

Versione a 38 byte:

for(int*x=s;putchar(strtol(x,&x,2)););

O solo 31 byte se s è un puntatore:

while(putchar(strtol(s,&s,2)));

Non penso che questo sia esattamente come dovrebbe essere usato per e mentre il ciclo ... ma funziona.


6

Pyth , 12

smCv+"0b"dPZ

Nota che s non è una variabile legale in Pyth, quindi ho usato Z invece.

Spiegazione:

        print(
s             sum(
m                 map(lambda d:
C                     chr(
v                         eval(
+"0b"d                         "0b"+d)),
P                     split(
Z                           Z))))

Esempio:

=Z"<the binary string from above>"smCv+"0b"dPZ
Hello World

Il fatto che non usi gli spazi bianchi nella formattazione (qui ti guardiamo Python) è un grande +1
Pharap

@Pharap Sì, un modo di vedere Pyth è Python con tutti gli elementi che gli fanno rimuovere più personaggi, come spazi bianchi, parentesi, token multi-personaggio, ecc.
isaacg

Non conosco Pyth, ma non risparmierebbe 4 caratteri da usare id2al posto di v+"0b"d? In ogni caso, questo è sia illeggibile che bello.
DLosc,

@DLosc Ho aggiunto quella funzione a Pyth dopo che questa domanda è stata posta, in gran parte a causa di questa domanda. Sarebbe più breve con l'attuale Pyth, ma oggi Pyth non è consentito per questa sfida.
isaacg,

Vedo. Mi chiedevo se potesse essere qualcosa del genere.
DLosc,

6

codice macchina x86 su DOS - 22 byte

00000000  30 d2 b4 08 cd 21 2c 30  72 06 d0 e2 08 c2 eb f2  |0....!,0r.......|
00000010  b4 02 cd 21 eb ea                                 |...!..|

Dal momento che non ci sono variabili stringa reali nel codice macchina (e in particolare, nessuna variabile denominata " s") ho optato per stdin come input.

Input NASM:

    org 100h

section .text

start:
    xor dl,dl
loop:
    mov ah,8
    int 21h
    sub al,'0'
    jb print
    shl dl,1
    or dl,al
    jmp loop
print:
    mov ah,2
    int 21h
    jmp start

6

Powershell ( 52 49)

-join(-split$s|%{[char][convert]::ToInt16($_,2)})

Ciclo semplice su stringa binaria in $ s. Dover includere il [convert] uccide il mio punteggio però.

EDIT: C'è davvero solo un modo per farlo in Powershell, wowie. Sia io che Joey abbiamo avuto praticamente la stessa risposta lavorando in modo indipendente!

Ingresso:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Produzione:

Hello World

1
È possibile utilizzare l'operatore di divisione unaria, salvando tre caratteri (a quel punto le nostre risposte sono identiche ... grande sorpresa ;-)).
Joey,

@Joey Ohh, buon punto! Non riesco a credere che mi sia perso. Ricevi il +1 da me per averlo catturato, grazie!
fuandon

5

Mathematica, 52 byte

Ah, i nomi adorabili delle funzioni di Mathematica

f=FromCharacterCode[#~FromDigits~2&/@StringSplit@#]&

5

Perl 33 32

Modifica: soluzione aggiornata, 32.

say$s=~s/\d+ ?/chr oct"0b$&"/rge

Soluzione precedente (33):

$_=$s;say map{chr oct"0b$_"}split

o

say map{chr oct"0b$_"}split/ /,$s

Test:

perl -E '$s="1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100";$_=$s;say map{chr oct"0b$_"}split'

5

J (23)

u:;(#.@:("."0))&.>cut s

Test:

   s=:'1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100'
   u:;(#.@:("."0))&.>cut s
Hello World

Spiegazione:

                  cut s    NB. split S on spaces
   (          )&.>         NB. for each element
        ("."0)             NB. evaluate each character
      @:                   NB. and
    #.                     NB. convert bitstring to number
  ;                        NB. unbox each number
u:                         NB. convert to ASCII


4

Python shell  44  40 caratteri

''.join(chr(int(x,2))for x in s.split())

Grazie per l'aiuto Griffin .


'' .join (chr (int (x, 2)) per x in s.split ())
Griffin

4

APL (15)

⎕UCS{2⊥⍎¨⍕⍵}¨⍎s

Test:

      s←'1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100'
      ⎕UCS{2⊥⍎¨⍕⍵}¨⍎s
Hello World

Spiegazione:

  • ⍎s: valuta s, trasformandolo in una matrice di numeri interi. Le matrici sono scritte come numeri separati da spazi, quindi questo si divide s.
  • {... : per ogni elemento:
    • ⍕⍵: trasforma il numero in una stringa
    • ⍎¨: valuta ogni singola cifra, fornendo una stringa di bit
    • 2⊥: decodifica base-2, fornendo i numeri
  • ⎕UCS: ottieni il carattere per ogni numero

Se non diversamente specificato, dovresti contare i byte anziché i caratteri: codegolf.stackexchange.com/tags/code-golf/info :)
Averroes,

1
@Averroes: il set di caratteri APL si inserisce in un byte con spazio libero: frankenstein.dns.org.uk/~marinus/aplcharset.png
marinus

Ah, non lo sapevo. Colpa mia. Scusate!
Averroè,

4

PHP (61)

<?=join(array_map('chr',array_map('bindec',explode(' ',$s))))

foreach(str_split($s,8)as$v)echo chr(bindec($v));
Jörg Hülsermann,

@ JörgHülsermann la codifica potrebbe saltare gli zeri iniziali, quindi str_split($s,8)non funzionerà. foreach(explode(' ',$s)as$v)echo chr(bindec($v));sarebbe valido ma non ho intenzione di modificare una delle mie prime risposte PPGC che chiaramente non è comunque realmente giocata a golf. Grazie lo stesso!
Christoph,

4

Bacco , 25 byte

S,' 'j:A=(Ö,2,10b:c),A¨

Spiegazione:

S,' 'j dividere la stringa S per lo spazio vuoto e la converte in un blocco (una sorta di matrice).

:A= ottenere il blocco precedente e assegnarlo a una variabile.

(),A¨ per ogni elemento in A

Ö,2,10bLeggi l'elemento corrente (rappresentato da Ö) nella base 2 e trasformalo nella base 10.

:c ottieni il valore precedente e stampa come carattere



3

C - 63

dato che C non ha un convertitore di base 2 nella libreria standard: prova qui
modifica: c'è, sono troppo stupido per saperlo

r;f(char*s){for(;*s;(*s|32)-32||(putchar(r),r=0))r=2*r|*s++&1;}

3

Run Lunghezza codificato Brainfuck, 49 byte

Dato che non ci sono variabili in Brainfuck, ho usato solo input e output standard.

Il codice 32+deve essere interpretato come 32 +s dall'interprete. Sostituiscili semplicemente se l'interprete non supporta RLE.

>,[32->+<[16-<[>++<-]>[<+>-]>-<]>[<<.[-]>>-]<,]<.

Versione estesa (non RLE): (91 byte)

>,[-------------------------------->+<[----------------<[>++<-]>[<+>-]>-<]>[<<.[-]>>-]<,]<.

Il codice presuppone che EOF sia codificato come 0.

Spiegazione

Viene utilizzato il seguente layout:

+---+---+------+
| x | a | flag |
+---+---+------+

Dove si xtrova il byte ASCII da stampare, aè un carattere dall'input standard ed flagè 1 se aera uno spazio.

>,            Read a character a into the second cell
[             While not EOF: 
  32-           Decrease a by 32 (a -= ' ')
  >+<           Set the flag to 1 
  [             If a was not a space:
    16-           Decrease by 16 more ('0' == 32+16)
    <[>++<-]      a += 2*x
    >[<+>-]       Move it back (x = a)
    >-<           Reset the flag, it was not a space.
  ]>
  [             If a was a space (flag == 1):
    <<.[-]        Print and reset x
    >>-           Reset the flag
  ]
  <,            Read the next caracter a
]
<.            Print the last character x

1
+1 Perché tutto dovrebbe avere un'implementazione brainfuck.
Pharap,

"Run Length Encoded Brainfuck" è una lingua separata? Non riesco a trovare un interprete.
mbomb007,

3

Java 8: 60 byte

Utilizzo di lambdas in Java 8 (75 byte):

Arrays.stream(s.split(" ")).reduce("",(a,b)->a+(char)Byte.parseByte(b,2));

E se si consentono le importazioni statiche (che alcuni qui utilizzati) è (61 byte):

stream(s.split(" ")).reduce("",(a,b)->a+(char)parseInt(b,2))

Una versione un po 'più corta usando for loop (60 byte):

for(String n:s.split(" ")){out.print((char)parseInt(n,2));}

2
Cosa, in realtà hanno fatto un rimpiazzo per la mostruosità nota come classe anonima? Eccezionale.
Seequ,

@Sieg sì Java ha anche lambda / chiusure ora, ma è principalmente zucchero sintetico in cima a classi anonime ... (ovviamente)
Roy van Rijn

3

Clojure 63 (o 57)

L'impianto all-Clojure:

(apply str(map #(char(read-string(str"2r"%)))(re-seq #"\d+"s)))

Con interoperabilità Java:

(apply str(map #(char(Long/parseLong % 2))(.split s" ")))

Sessione REPL:

golf> (def s "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100")
#'golf/s
golf> (apply str(map #(char(read-string(str"2r"%)))(re-seq #"\d+"s)))
"Hello World"
golf> (apply str(map #(char(Long/parseLong % 2))(.split s" ")))
"Hello World"

3

QBasic, 103

s$=s$+" ":FOR i=1 TO LEN(s$):c$=MID$(s$,i,1):IF c$=" "THEN n=0:r$=r$+CHR$(n)ELSE n=n*2+VAL(c$)
NEXT:?r$

Che cosa? Non abbiamo funzioni fantasiose da binario a decimale qui. Fallo da solo!

Sto contando la newline (che ritengo necessaria per ottenere if-then-else senza un END IF) come un byte, per questo meta post . Non so se QB64 su Windows accetterebbe o meno un file di codice in questo modo. Probabilmente non ha molta importanza.


2

NodoJS - 62

Buffer(s.split(' ').map(function(a){return parseInt(a,2)}))+''

PHP - 75

array_reduce(explode(' ', $b),function($a,$b){return $a.chr(bindec($b));});

come si esegue nodejs con compatibilità es6? l'ultimo non supporta ancora le funzioni lambda per me
bebe

Le funzioni di freccia @bebe sono implementate in v8 ma non sono ancora integrate con il nodo. Modificherò il mio post.
cPu1,

@ cPu1 lavorano per me
username.ak il

2

JavaScript 111

Ciò esegue la conversione numerica senza analisi o valutazione. Leggendo la stringa all'indietro e contando i bit, imposta il bit x se è uno. Quando viene trovato uno spazio, il numero viene convertito in un carattere e viene avviato un nuovo numero 0 per l'impostazione dei bit.

x=n=0,w='',s=' '+s
for(i=s.length;i--;){m=s[i]
if(m==1)n|=1<<x
x++
if(m==' ')w=String.fromCharCode(n)+w,n=x=0
}

1
+1 per averlo fatto alla vecchia maniera - mi ha ispirato a scrivere anche una versione di QBasic.
DLosc,

Non valido, deve essere una funzione o un programma completo (uno che accetta input)
ASCII il

2

Groovy 64

{it.split(" ").collect{Integer.parseInt(it,2) as char}.join("")}

2

CJam, 11 byte

NS/{:~2bc}/

s non è un nome di variabile legale in CJam, quindi ho scelto N invece.

Provalo online.

Esempio di esecuzione

$ cjam <(echo '
> "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
> :N;
> NS/{:~2bc}/
> '); echo
Hello World

Come funziona

NS/            " Split N at spaces.                            ";
   {     }/    " For each chunk:                               ";
    :~         "   Evaluate each character ('0' ↦ 0, '1' ↦ 1). ";
      2b       "   Convert from base 2 array to integer.       ";
        c      "   Cast to character.                          ";

2

Haskell - 48 (+13 importazioni (?))

Ecco il mio primo tentativo di golf a Haskell.

map(chr.foldl1((+).(*2)).map digitToInt)$words s

Devi importare Data.Char

utilizzo (in ghci):

Prelude> :m +Data.Char
Prelude Data.Char> let s = "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
Prelude Data.Char> map(chr.foldl1((+).(*2)).map digitToInt)$words s
"Hello World"

Spiegazione:

map(chr.foldl1((+).(*2)).map digitToInt)$words s
                                        $words s -- split s on spaces into a list
                         map digitToInt          -- convert each digit in input string to int
              ((+).(*2))                         -- a function that multiplies its first 
-- argument by 2, then adds the second argument
        foldl1((+).(*2)).map digitToInt          -- fold the above over the list of ints: 
-- in other words this is a function that reads strings as binary and gives the value as int
   (chr.foldl1((+).(*2)).map digitToInt)         -- cast to character
map(chr.foldl1((+).(*2)).map digitToInt)$words s -- map our function over the list of words

Spero di aver seguito correttamente le convenzioni sulla valutazione delle importazioni. Sentiti libero di modificare in una correzione se non l'ho fatto. Ho trattato ": m + Data.Char" necessario per l'importazione in ghci come 13.
ballesta25

1

GNU Sed, 19 byte

Ispirato da un'eccellente risposta al trauma digitale.

golfed

s/\w*/dc -e2i&P;/eg

Test

echo 1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100|\
sed 's/\w*/dc -e2i&P;/eg'

Hello World

1

Pyth, 7 byte (non concorrenti)

smCid2c

Accetta l'input come stringa.

Provalo!


Contrassegnato come non competitivo perché il linguaggio è più recente della sfida.
mbomb007,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.