Преобразовать строку двоичных символов в эквиваленты ASCII


27

Возьмите строку двоичных символов, разделенных пробелом, и преобразуйте ее в строку ASCII.

Например...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Преобразовал бы в ...

Hello World

Двоичная строка будет храниться в переменной с именем s.

Это задача кода-гольфа, поэтому выигрывает самое короткое решение.


15
+1 за вызов без истории и других рукописей, прямо к делу
bebe

9
@bebe Вымышленные фантастические закуски составляют половину веселья.
qwr

Здравствуйте. Давайте представим, что ваша технология настолько продвинута, что не поддерживает ASCII. Будет ли разрешено преобразовывать в собственную кодировку символов или нужно будет преобразовать ASCII в собственную кодировку символов? Я думаю ZX81здесь.
Шон Бебберс

Ответы:


10

Руби, 36 32

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

Или 31

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

Оптимизация благодаря Chron


1
Можно заменить .join""на , *""чтобы сэкономить несколько символов. Вы также можете сделать это с помощью gsub вместо split + map + join, что-то вроде: s.gsub(/\w+ ?/){$&.to_i(2).chr}(31 символ).
Пол Престиж

2
s.gsub(/\d+./){$&.to_i(2).chr}работает, и это 30 символов, я понятия не имею, почему это работает, хотя. Не .должно соответствовать в последний раз, но это соответствует.
Эддисон

10

JavaScript (ES6) 49 55 56 64

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

Изменить Принятие предложения @bebe - спасибо
Edit2 Не знал о двоичном числовом литерале - спасибо @kapep
Edit3 Wow 6, не сохранено 4 байта thx @ETHproductions

Объяснение в соответствии с просьбой в комментариях

String.replace может принимать 2 аргумента:

  • регулярное выражение /\d+./g: одна или несколько цифр, за которыми следует один другой символ - флаг g указывает на поиск в шаблоне более одного раза
  • функция, указанная здесь в формате стрелки, где аргумент (x) будет найденной строкой (последовательность цифр, за которой следует пробел), а значение функции - это то, что заменяется (в данном случае, один символ из код).

Стоит отметить, что в конце строки регулярное выражение соответствует последовательности цифр без пробела, в этом случае точка соответствует последней цифре. Попробуйте «123» .match (/ (\ d +) ./) для проверки.

(Тем не менее) один из самых многословных кусочков JavaScript когда-либо ...
(Назначение строки s не учитывается)

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

Можете ли вы объяснить, что /\d+./g,x=>делает?
Излин

1
@izlin Я добавил некоторые объяснения к ответу
edc65

Я знаю, что это старый ответ, но вы можете перейти eval('0b'+x)на '0b'+x-04 байта.
ETHproductions

8

Bash + общие утилиты Linux, 25 байт

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

DC объяснение

  • нажмите 2 в стек; поп и использовать в качестве входного радиуса
  • вставить входную строку в стек (все значения одновременно)
  • Определить рекурсивный макрос mдля:
    • всплывающее, затем распечатайте значение как ASCII
    • толкать глубину стека
    • нажмите 0, чтобы сложить
    • поп топ 2 значения стека; сравнить и вызвать mмакрос, если стек не пустой
  • дубликат вершины стека (определение макроса)
  • поп и сохранить макрос для mрегистрации
  • поп и выполнить макрос

Поскольку мы сначала помещаем всю двоичную строку в стек, когда мы выталкиваем каждое значение, мы получаем строку в обратном порядке. Поэтому мы используем revутилиту, чтобы исправить это.

Пример использования:

$ 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)})

РЕДАКТИРОВАТЬ: не видел другой ответ PowerShell. Но, по сути, существует только один способ решения этой проблемы.


7

C - 57 43 38/31

38-байтовая версия:

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

Или только 31 байт, если s является указателем:

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

Я не думаю, что это именно то, для чего и когда цикл должен использоваться ... но он работает.


6

Пиф , 12

smCv+"0b"dPZ

Обратите внимание, что s не является допустимой переменной в Pyth, поэтому я использовал Z вместо.

Объяснение:

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

Пример:

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

Тот факт, что он не использует пробелы в форматировании (здесь вы смотрите на Python), является главным +1
Pharap

@Pharap Да, один из способов взглянуть на Pyth - это Python со всеми элементами, которые заставляют его убирать больше символов, таких как пробелы, скобки,
многосимвольные

Я не знаю Pyth, но разве он не сохранит 4 символа для использования id2вместо v+"0b"d? В любом случае это нечитаемо и круто.
DLosc

@DLosc Я добавил эту функцию в Pyth после того, как был задан этот вопрос, в значительной степени из-за этого вопроса. Это было бы короче с сегодняшним Pyth, но современный Pyth не разрешен для этого вызова.
Исаак

Понимаю. Я задавался вопросом, может ли это быть что-то подобное.
DLosc

6

машинный код x86 на DOS - 22 байта

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

Поскольку в машинном коде нет реальных строковых переменных (и, в частности, переменных с именем " s"), я выбрал stdin в качестве входных данных.

Вход 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)})

Простой цикл над двоичной строкой в ​​$ s. Однако необходимость включить [convert] убивает мой счет.

РЕДАКТИРОВАТЬ: Есть действительно только один способ осуществить это в Powershell, вау. Мы с Джои получили одинаковый ответ, работая независимо!

Входные данные:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Выход:

Hello World

1
Вы можете использовать унарный оператор разбиения, сохраняя три символа (в этот момент наши ответы идентичны ... большой сюрприз ;-)).
Джои

@ Джой О, хорошая мысль! Не могу поверить, что я пропустил это. Вы получаете +1 от меня за то, что поймали это, спасибо!
Фуандон


5

Perl 33 32

Изменить: обновленное решение, 32.

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

Предыдущее решение (33):

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

или

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

Тест:

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

Тест:

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

Объяснение:

                  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

APL (15)

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

Тест:

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

Объяснение:

  • ⍎s: оценить s, превратив его в массив целых чисел. Массивы записываются в виде чисел , разделенных пробелами, поэтому это расколы s.
  • {... : для каждого элемента:
    • ⍕⍵: превратить число обратно в строку
    • ⍎¨: оценить каждую отдельную цифру, давая цепочку
    • 2⊥: расшифровка базы-2 с указанием чисел
  • ⎕UCS: получить символ для каждого номера

Если не указано иное , вы должны рассчитывать байт вместо символов: codegolf.stackexchange.com/tags/code-golf/info :)
Аверроэс

1
@Averroes: кодировка APL вписывается в байт с запасом места
marinus

Ах, я этого не знал. Виноват. Сожалею!
Аверроэс

4

PHP (61)

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

foreach(str_split($s,8)as$v)echo chr(bindec($v));
Йорг Хюльсерманн

@ JörgHülsermann кодировка может пропускать начальные нули, поэтому str_split($s,8)не будет работать. foreach(explode(' ',$s)as$v)echo chr(bindec($v));будет действительным, но я не планирую редактировать один из моих первых ответов PPGC, который в любом случае явно не в гольфе. Все равно спасибо!
Кристоф

4

Вакх , 25 байт

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

Объяснение:

S,' 'j разбить строку S на пустое пространство и преобразовать ее в блок (своего рода массив).

:A= получить предыдущий блок и передать его в переменную.

(),A¨ для каждого элемента в

Ö,2,10bСчитайте текущий элемент (обозначенный как Ö) в базе 2 и преобразуйте его в базу 10.

:c получить предыдущее значение и распечатать как символ



3

С - 63

поскольку в стандартной библиотеке C нет конвертера base 2: протестируйте здесь
edit: есть, я просто слишком глуп, чтобы знать об этом

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

3

Длина цикла, закодированный Brainfuck, 49 байтов

Поскольку в Brainfuck нет переменных, я просто использовал вместо них стандартный ввод и вывод.

Код 32+должен интерпретироваться интерпретатором как 32 +с. Просто замените их вручную, если ваш переводчик не поддерживает RLE.

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

Расширенная (не RLE) версия: (91 байт)

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

Код предполагает, что EOF кодируется как 0.

объяснение

Используется следующий макет:

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

Где xбайт ASCII для печати, aэто символ из стандартного ввода и flag1, если это aбыл пробел.

>,            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 Потому что у всего должна быть реализация мозгового штурма.
Pharap

Является ли «Brainfuck кодированной длины пробега» реальным отдельным языком? Я не могу найти переводчика.
mbomb007

3

Java 8: 60 байт

Использование лямбды в Java 8 (75 байт):

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

И если вы разрешите статический импорт (который некоторые здесь использовали), то это (61 байт):

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

Немного более короткая версия, использующая цикл for (60 байт):

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

2
Что, они фактически сделали замену чудовищу, известному как анонимный класс? Потрясающе.
Seequ

@Sieg да У Java теперь есть и лямбды / замыкания, но в основном это синтетический сахар поверх анонимных классов ... (очевидно)
Рой ван Рейн

3

Clojure 63 (или 57)

All-Clojure подразумевает:

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

С взаимодействием Java:

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

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$

Какая? У нас нет причудливых двоично-десятичных функций здесь. Сделай сам!

Я считаю новую строку (которую я считаю необходимой, чтобы получить if-then-else без символа END IF) как один байт для каждого мета-поста . Я не знаю, будет ли QB64 в Windows принимать файл кода таким образом или нет. Вероятно, это не имеет большого значения.


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

как вы запускаете nodejs с совместимостью с es6? последняя все еще не поддерживает лямбда-функции для меня
bebe

@bebe Функции стрелок реализованы в v8, но они еще не интегрированы с узлом. Я отредактирую свой пост.
cPu1

@ cPu1 они работают на меня
username.ak

2

JavaScript 111

Это делает преобразование чисел без parseInt или eval. Читая строку в обратном направлении и считая биты, она устанавливает бит x, если он равен единице. Когда пробел найден, число преобразуется в символ и запускается новый номер 0 для установки битов.

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 за то, что сделал это старомодным способом - вдохновил меня на написание и версии QBasic.
DLosc

Неверно, должна быть функция или полная программа (та, которая принимает данные)
только ASCII


2

CJam, 11 байт

NS/{:~2bc}/

s не является именем переменной в юридической CJam, поэтому я выбрал N вместо.

Попробуйте онлайн.

Пример запуска

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

Как это работает

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 импорт (?))

Вот моя первая попытка игры в гольф на Хаскеле.

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

Вам нужно импортировать Data.Char

использование (в 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"

Объяснение:

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

Надеюсь, я правильно следовал правилам подсчета очков в отношении импорта. Не стесняйтесь редактировать в исправлении, если я не сделал. Я обработал ": m + Data.Char", необходимый для импорта в ghci, как 13.
ballesta25

1

GNU Sed, 19 байтов

Вдохновленный отличным ответом @Digital Trauma.

Golfed

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

Тест

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

Hello World

1

Pyth, 7 байт (не конкурирует)

smCid2c

Принимает ввод в виде строки.

Попытайся!


Помечено как не конкурирующее, потому что язык новее, чем вызов.
mbomb007

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.