Convertir une chaîne de caractères binaires en équivalents ASCII

27

Prenez une chaîne de caractères binaires séparés par un espace et convertissez-la en chaîne ASCII.

Par exemple...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Se convertirait en ...

Hello World

La chaîne binaire sera stockée dans une variable appelée s.

Il s'agit d'un défi de code-golf, donc la solution la plus courte l'emporte.

James Williams
la source
15
+1 pour avoir fait un défi sans histoire et autres friperies, droit au but
bebe
9
@bebe Les friperies fantastiques fictives forment la moitié du plaisir.
qwr
Bonjour. Imaginons que votre technologie soit si avancée qu'elle ne prenne pas en charge ASCII. Serait-il autorisé à convertir en encodage de caractères natifs, ou devrait-il convertir ASCII en encodage de caractères natifs? Je pense ZX81ici.
Shaun Bebbers

Réponses:

10

Rubis, 36 32

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

Ou 31

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

Optimisations grâce à Chron

Kroltan
la source
1
Vous pouvez remplacer .join""pour *""enregistrer quelques caractères. Vous pouvez également le faire avec gsub au lieu de split + map + join, quelque chose comme: s.gsub(/\w+ ?/){$&.to_i(2).chr}(31 caractères).
Paul Prestidge
2
s.gsub(/\d+./){$&.to_i(2).chr}fonctionne et c'est 30 caractères, je ne sais pas pourquoi cela fonctionne bien. Le .ne devrait pas correspondre la dernière fois mais c'est le cas.
addison
10

JavaScript (ES6) 49 55 56 64

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

Edit Accepter la suggestion @bebe - merci
Edit2 Ne connaissait pas le littéral numérique binaire - merci @kapep
Edit3 Wow 6 pas 4 octets enregistrés thx @ETHproductions

Explication demandée dans les commentaires

String.replace peut prendre 2 arguments:

  • expression régulière /\d+./g: un ou plusieurs chiffres suivis d'un caractère différent - le drapeau g spécifie de rechercher le motif plus d'une fois
  • une fonction, ici spécifiée sous forme de flèche, où l'argument (x) sera la chaîne trouvée (la séquence de chiffres éventuellement suivie d'un espace) et la valeur de la fonction est ce qui est remplacé (dans ce cas, le caractère unique de le code).

Il convient de noter qu'à la fin de la chaîne, l'expression rationnelle correspond à la séquence de chiffres sans espace de fin, dans ce cas, le point correspond au dernier chiffre. Essayez '123'.match (/ (\ d +) ./) pour vérifier.

(Toujours) l'un des morceaux de javascript les plus verbeux jamais ...
(L'affectation à la chaîne n'est pas comptée)

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)

edc65
la source
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
Pouvez-vous expliquer ce que cela /\d+./g,x=>fait?
izlin
1
@izlin J'ai ajouté quelques explications à la réponse
edc65
Je sais que c'est une vieille réponse, mais vous pouvez changer eval('0b'+x)pour '0b'+x-0sauver 4 octets.
ETHproductions
8

Bash + utilitaires Linux communs, 25 octets

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

explication dc

  • poussez 2 vers la pile; pop et utiliser comme radix d'entrée
  • pousser la chaîne d'entrée pour l'empiler (toutes les valeurs à la fois)
  • Définissez une macro récursive mpour:
    • pop, puis imprimer la valeur en ASCII
    • pousser la profondeur de pile pour empiler
    • poussez 0 pour empiler
    • pop 2 valeurs de pile supérieures; comparer et appeler la mmacro si la pile n'est pas vide
  • Dupliquer le haut de la pile (définition de macro)
  • pop et enregistrer la macro pour vous minscrire
  • pop et exécuter la macro

Parce que nous poussons d'abord la chaîne binaire entière vers la pile, lorsque nous sautons chaque valeur, nous nous retrouvons avec la chaîne inversée. Nous utilisons donc l' revutilitaire pour corriger cela.

Exemple d'utilisation:

$ s="1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
$ dc<<<2i$s[Pz0\<m]dsmx|rev
Hello World
$ 
Traumatisme numérique
la source
7

PowerShell, 49

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

EDIT: Je n'ai pas vu l'autre réponse PowerShell. Mais il n'y a essentiellement qu'une seule façon de résoudre ce problème.

Joey
la source
7

C - 57 43 38/31

Version 38 octets:

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

Ou seulement 31 octets si s est un pointeur:

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

Je ne pense pas que ce soit exactement la façon dont les boucles sont censées être utilisées ... mais cela fonctionne.

Ian D. Scott
la source
6

Pyth , 12

smCv+"0b"dPZ

Notez que s n'est pas une variable légale en Pyth, j'ai donc utilisé Z à la place.

Explication:

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

Exemple:

=Z"<the binary string from above>"smCv+"0b"dPZ
Hello World
isaacg
la source
Le fait qu'il n'utilise pas d'espaces dans le formatage (voici Python) est un +1 majeur
Pharap
@Pharap Oui, une façon de voir Pyth est que c'est Python avec tous les éléments qui lui font enlever plus de caractères, comme les espaces blancs, les parenthèses, les jetons multi-caractères, etc.
isaacg
Je ne connais pas Pyth, mais ne sauverait-il pas 4 caractères à utiliser id2à la place de v+"0b"d? En tout cas, c'est à la fois illisible et cool.
DLosc
@DLosc J'ai ajouté cette fonction à Pyth après que cette question a été posée, en grande partie à cause de cette question. Il serait plus court avec le Pyth d'aujourd'hui, mais le Pyth actuel n'est pas autorisé pour ce défi.
isaacg
Je vois. Je me demandais si ça pouvait être quelque chose comme ça.
DLosc
6

code machine x86 sous DOS - 22 octets

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                                 |...!..|

Puisqu'il n'y a pas de vraies variables de chaîne dans le code machine (et en particulier, aucune variable nommée " s"), j'ai choisi stdin en entrée.

Entrée 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
Matteo Italia
la source
6

Powershell ( 52 49)

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

Boucle simple sur une chaîne binaire dans $ s. Le fait d'inclure le [converti] tue cependant mon score.

EDIT: Il n'y a vraiment qu'une seule façon de réussir cela dans Powershell, wowie. Joey et moi avons obtenu à peu près la même réponse en travaillant indépendamment!

Contribution:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Sortie:

Hello World
Fuandon
la source
1
Vous pouvez utiliser l'opérateur de division unaire, en enregistrant trois caractères (auquel cas nos réponses sont identiques ... grosse surprise ;-)).
Joey
@Joey Ohh, bon point! Je ne peux pas croire que j'ai raté ça. Vous obtenez le +1 de moi pour avoir attrapé cela, merci!
fuandon
5

Mathematica, 52 octets

Ah, les beaux noms de fonctions de Mathematica

f=FromCharacterCode[#~FromDigits~2&/@StringSplit@#]&
Martin Ender
la source
5

Perl 33 32

Edit: Solution mise à jour, 32.

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

Solution précédente (33):

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

ou

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

Tester:

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

J (23)

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

Tester:

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

Explication:

                  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
marinus
la source
4

Golfscript - 21

' '/{1/{~}%2base}%''+

Vous pouvez le tester ici .

Kyle McCormick
la source
4

Coque Python  44  40 caractères

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

Merci pour l'aide Griffin .

James Williams
la source
'' .join (chr (int (x, 2)) for x in s.split ())
Griffin
4

APL (15)

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

Tester:

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

Explication:

  • ⍎s: évaluer s, en le transformant en un tableau d'entiers. Les tableaux sont écrits sous forme de nombres séparés par des espaces, donc cela se divise s.
  • {... : pour chaque élément:
    • ⍕⍵: remettez le nombre en chaîne
    • ⍎¨: évaluer chaque chiffre individuel, en donnant une chaîne de bits
    • 2⊥: décodage base-2, donnant les chiffres
  • ⎕UCS: obtenir le caractère pour chaque numéro
marinus
la source
Sauf indication contraire, vous devez compter les octets au lieu des caractères: codegolf.stackexchange.com/tags/code-golf/info :)
Averroes
1
@Averroes: le jeu de caractères APL tient dans un octet avec de la place à revendre: frankenstein.dns.org.uk/~marinus/aplcharset.png
marinus
Ah, je ne le savais pas. Ma faute. Désolé!
Averroes
4

PHP (61)

<?=join(array_map('chr',array_map('bindec',explode(' ',$s))))
Christoph
la source
foreach(str_split($s,8)as$v)echo chr(bindec($v));
Jörg Hülsermann
@ JörgHülsermann l'encodage peut sauter des zéros str_split($s,8)non significatifs donc ne fonctionnera pas. foreach(explode(' ',$s)as$v)echo chr(bindec($v));serait valide mais je ne prévois pas d'éditer une de mes premières réponses PPGC qui n'est clairement pas vraiment jouée de toute façon. Merci quand même!
Christoph
4

Bacchus , 25 octets

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

Explication:

S,' 'j diviser la chaîne S par l'espace vide et le convertit en un bloc (une sorte de tableau).

:A= obtenir le bloc précédent et l'assigner à une variable A.

(),A¨ pour chaque élément dans A

Ö,2,10bLisez l'élément actuel (représenté par Ö) dans la base 2 et transformez-le en base 10.

:c obtenir la valeur précédente et imprimer en tant que char

Averroes
la source
3

GolfScript 23

' '/{[{49=}/]2base}%''+

Test en ligne ici .

Cristian Lupascu
la source
3

C - 63

puisque C n'a pas de convertisseur base 2 dans la bibliothèque standard: testez ici
éditez: il y en a, je suis juste trop stupide pour le savoir

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

Run Brainfuck encodé en longueur, 49 octets

Puisqu'il n'y a pas de variables dans Brainfuck, j'ai juste utilisé des entrées et sorties standard à la place.

Le code 32+doit être interprété comme 32 +s par l'interprète. Remplacez-les simplement manuellement si votre interprète ne prend pas en charge RLE.

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

Version étendue (non RLE): (91 octets)

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

Le code suppose que EOF est codé comme 0.

Explication

La disposition suivante est utilisée:

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

xest l'octet ASCII à imprimer, aest le caractère a de l'entrée standard et flagest 1 si aétait un espace.

>,            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
Hjulle
la source
1
+1 Parce que tout devrait avoir une implémentation brainfuck.
Pharap
"Run Length Encoded Brainfuck" est-il vraiment une langue distincte? Je ne trouve pas d'interprète.
mbomb007
3

Java 8:60 octets

Utilisation de lambdas dans Java 8 (75 octets):

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

Et si vous autorisez les importations statiques (que certains utilisent ici), c'est (61 octets):

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

Une version un peu plus courte utilisant la boucle for (60 octets):

for(String n:s.split(" ")){out.print((char)parseInt(n,2));}
Roy van Rijn
la source
2
Quoi, ils ont en fait remplacé la monstruosité connue sous le nom de classe anonyme? Impressionnant.
seequ
@Sieg oui Java a aussi des lambdas / fermetures, mais c'est surtout du sucre synthétique en plus des classes anonymes ... (évidemment)
Roy van Rijn
3

Clojure 63 (ou 57)

Le tout-Clojure implique:

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

Avec Java interop:

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

Session 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"
YosemiteMark
la source
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$

Quelle? Nous n'avons pas de fonctions fantaisie binaires à décimales ici. Fais le toi-même!

Je compte la nouvelle ligne (qui je pense est nécessaire pour obtenir le if-then-else sans an END IF) comme un octet, par cette méta-publication . Je ne sais pas si QB64 sous Windows accepterait un fichier de code de cette façon ou non. Peu importe probablement peu.

DLosc
la source
2

NodeJS - 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));});
cPu1
la source
comment exécutez-vous nodejs avec la compatibilité es6? la dernière ne prend toujours pas en charge les fonctions lambda pour moi
bebe
Les fonctions @bebe Arrow sont implémentées dans la v8 mais elles ne sont pas encore intégrées au nœud. Je vais modifier mon message.
cPu1
@ cPu1 ils travaillent pour moi
username.ak
2

JavaScript 111

Cela fait la conversion des nombres sans parseInt ou eval. En lisant la chaîne en arrière et en comptant les bits, il définit le bit x s'il est un. Lorsqu'un espace est trouvé, le nombre est converti en caractère et un nouveau nombre 0 est démarré pour définir les bits.

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
}
marteau-de-loup
la source
1
+1 pour l'avoir fait à l'ancienne - m'a aussi inspiré à écrire une version QBasic.
DLosc
Non valide, doit être une fonction ou un programme complet (celui qui prend une entrée)
ASCII uniquement le
2

Groovy 64

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

CJam, 11 octets

NS/{:~2bc}/

s n'est pas un nom de variable légal dans CJam, j'ai donc choisi N à la place.

Essayez-le en ligne.

Exemple d'exécution

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

Comment ça marche

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.                          ";
Dennis
la source
2

Haskell - 48 (+13 importations (?))

Voici ma première tentative de golf à Haskell.

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

Vous devez importer Data.Char

utilisation (en 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"

Explication:

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
ballesta25
la source
J'espère que j'ai suivi correctement les conventions de notation concernant les importations. N'hésitez pas à éditer une correction si ce n'est pas le cas. J'ai traité le ": m + Data.Char" nécessaire pour importer dans ghci comme 13.
ballesta25
1

GNU Sed, 19 octets

Inspiré par une excellente réponse @Digital Trauma.

Golfé

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

Tester

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

Hello World
Zeppelin
la source
1

Pyth, 7 octets (non concurrent)

smCid2c

Prend l'entrée comme chaîne.

Essayez!

KarlKastor
la source
Marqué non concurrent car la langue est plus récente que le défi.
mbomb007
1

05AB1E , 4 octets (non concurrent)

Sauvegardé 3 octets grâce à @Emigna

#CçJ

Essayez-le en ligne!

Urne de poulpe magique
la source
1
#CçJfonctionne également. Bien que dans cette version et dans votre version, vous ayez besoin ð¡au lieu de #si l'entrée ne peut être que de 1 caractère.
Emigna