将一串二进制字符转换为ASCII等效项


27

取一串用空格分隔的二进制字符,然后将其转换为ASCII字符串。

例如...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

将转换为...

Hello World

二进制字符串将存储在名为的变量中s

这是一个代码高尔夫挑战,因此最短的解决方案将获胜。


15
+1制作一个挑战没有故事和其他fripperies,开门见山
贝贝

9
@bebe虚拟幻想的小玩意儿占了一半。
qwr 2014年

你好。假设您的技术是如此先进,以至于它不支持ASCII。是否允许将其转换为本地字符编码,还是必须将ASCII转换为本地字符编码?我想ZX81在这里。
Shaun Bebbers

Answers:


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个字符)。
Paul Prestidge 2014年

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哇6 保存4个字节@ETHproductions

注释中要求的解释

String.replace 可以接受2个参数:

  • 正则表达式/\d+./g:一位或多位数字,后跟一个不同的字符-g标志指定多次搜索模式
  • 一个函数,这里以箭头格式指定,其中参数(x)将是找到的字符串(数字序列,最后是一个空格),并且该函数的值将被替换(在这种情况下,代码)。

值得注意的是,字符串末尾的regexp匹配数字序列,没有尾随空格,在这种情况下,点与最后一位数字匹配。尝试'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-0节省4个字节。
ETHproductions

8

Bash +常见的Linux utils,25个字节

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

直流说明

  • 将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)););

如果s是一个指针,则只有31个字节:

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

我认为这不是应该使用for和while循环的方式...但是它有效。


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的一切,使其采取更多的字符去掉,如空格,括号,多字符记号等要素
isaacg

我不认识Pyth,但是会不会保存4个字符以id2代替v+"0b"d?无论如何,这既不可读又很酷。
DLosc 2014年

@DLosc在问了这个问题后,我将该函数添加到了Pyth中,这在很大程度上是由于这个问题。使用今天的Pyth会更短一些,但是此挑战不允许使用今天的Pyth。
isaacg 2014年

我懂了。我想知道是否可能是这样。
DLosc 2014年

6

DOS上的x86机器代码-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中实现这一目标,哇。Joey和我两个人在独立工作时都得到了几乎相同的答案!

输入:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

输出:

Hello World

1
您可以使用一元拆分运算符,保存三个字符(这时我们的答案是相同的……很让人惊讶;-)。
2014年

@Joey Ohh,好点!不敢相信我错过了。您从我这里得到+1,谢谢!
Fuandon 2014年

5

Mathematica,52个字节

啊,Mathematica的可爱函数名称

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

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 :)
Averroes

1
@Averroes:APL字符集适合一个字节,并有剩余空间:frankenstein.dns.org.uk/~marinus/aplcharset.png
marinus

啊,我不知道。我的错。抱歉!
Averroes 2014年

4

PHP(61)

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

foreach(str_split($s,8)as$v)echo chr(bindec($v));
约尔格Hülsermann

@JörgHülsermann编码可能会跳过前导零,因此str_split($s,8)无法正常工作。foreach(explode(' ',$s)as$v)echo chr(bindec($v));会是有效的,但我不打算编辑我​​的第一个PPGC答案,而答案显然显然不是真的。还是很感谢你!
克里斯多夫(Christoph)

4

酒神,25个字节

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

说明:

S,' 'j 将字符串S拆分为空白,并将其转换为块(某种数组)。

:A= 获取先前的块并将其关联到A变量。

(),A¨ 对于A中的每个元素

Ö,2,10bÖ在base 2中读取当前元素(用表示),并将其转换为base 10。

:c 获取先前的值并打印为char



3

C-63

因为C在标准库中没有base 2转换器:在这里测试
编辑:那里,我太愚蠢,无法了解它

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

3

运行长度编码的Brainfuck,49个字节

由于Brainfuck中没有变量,因此我只使用标准输入和输出。

32+解释器应将代码解释为32 +s。如果您的解释器不支持RLE,只需手动更换它们。

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

扩展(非RLE)版本:(91字节)

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

该代码假定EOF编码为0。

说明

使用以下布局:

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

其中x是要打印的ASCII字节,a是来自标准输入的字符,flag如果a为空格则为1 。

>,            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,因为一切都应该有一个明智的实现。
法拉普2014年

“游程编码的Brainfuck”是一种单独的语言吗?我找不到翻译。
mbomb007 '03

3

Java 8:60个字节

在Java 8中使用lambda(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 2014年

@Sieg是的Java现在也有lambdas / closures,但是在匿名类的上面它主要是合成糖...(显然)
Roy van Rijn 2014年

3

Clojure 63(或57)

全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$

什么?我们这里没有花哨的二进制到十进制函数。自己做!

我在此meta post上将换行符(我认为这对于获取不带if-then-else而不是END IF)是一个字节。我不知道Windows上的QB64是否会以这种方式接受代码文件。大概没什么大不了的。


2

NodeJS62

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

PHP75

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

如何运行具有es6兼容性的nodejs?最新的版本对我仍然不支持lambda函数
Bebe 2014年

@bebe Arrow函数在v8中实现,但尚未与node集成。我将编辑我的帖子。
cPu1 2014年

@ cPu1他们为我工作
username.ak

2

JavaScript的111

这将执行数字转换而无需parseInt或eval。向后读取字符串并计数位,如果它是1,则将其设置为位x。找到空格后,该数字将转换为char并开始使用新的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 2014年

无效,必须是函数或完整程序(需要输入的程序)
仅ASCII的

2

Groovy 64

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

2

CJam,11个字节

NS/{:~2bc}/

小号不CJam一个合法的变量名,所以我选择ñ代替。

在线尝试。

运行示例

$ 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进口(?))

这是我在Haskell的第一次高尔夫尝试。

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答案的启发。

打高尔夫球

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.