Chuyển đổi một chuỗi các ký tự nhị phân thành tương đương ASCII


27

Lấy một chuỗi các ký tự nhị phân cách nhau bởi một khoảng trắng và chuyển đổi nó thành chuỗi ASCII.

Ví dụ...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Sẽ chuyển đổi sang ...

Hello World

Chuỗi nhị phân sẽ được lưu trữ trong một biến được gọi là s.

Đây là một thử thách golf-code nên giải pháp ngắn nhất sẽ thắng.


15
1 để thực hiện một thử thách mà không câu chuyện và hình ảnh rẻ tiền khác, thẳng vào vấn đề
bebe

9
@bebe Fripperies tưởng tượng hư cấu tạo thành một nửa niềm vui.
qwr

Xin chào. Hãy tưởng tượng rằng công nghệ của bạn tiên tiến đến mức nó không hỗ trợ ASCII. Nó có được phép chuyển đổi sang mã hóa ký tự gốc hay nó phải chuyển đổi ASCII sang mã hóa ký tự gốc? Tôi đang suy nghĩ ZX81ở đây.
Shaun Bebbers

Câu trả lời:


10

Ruby, 36 32

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

Hoặc 31

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

Tối ưu hóa nhờ Chron


1
Bạn có thể thay thế .join""cho *""tiết kiệm một vài ký tự. Bạn cũng có thể làm điều đó với gsub thay vì split + map + tham gia, đại loại như: s.gsub(/\w+ ?/){$&.to_i(2).chr}(31 ký tự).
Paul Prestidge

2
s.gsub(/\d+./){$&.to_i(2).chr}hoạt động và đó là 30 ký tự, tôi không biết tại sao nó hoạt động. Không .nên kết hợp lần trước nhưng nó không.
addison

10

JavaScript (ES6) 49 55 56 64

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

Sửa Chấp nhận @bebe gợi ý - nhờ
Edit2 Không biết về nhị phân số chữ - nhờ @kapep
Edit3 Wow 6 không 4 byte lưu @ETHproductions thx

Giải thích theo yêu cầu trong ý kiến

String.replace có thể lấy 2 đối số:

  • biểu thức chính quy /\d+./g: một hoặc nhiều chữ số theo sau bởi một ký tự khác nhau - cờ g chỉ định để tìm kiếm mẫu nhiều lần
  • một hàm, ở đây được chỉ định ở định dạng mũi tên, trong đó đối số (x) sẽ là chuỗi tìm thấy (chuỗi chữ số cuối cùng theo sau là khoảng trắng) và giá trị của hàm là giá trị được thay thế (trong trường hợp này là ký tự đơn từ mật mã).

Điều đáng chú ý là ở cuối chuỗi, biểu thức chính quy phù hợp với chuỗi các chữ số không có dấu cách, trong trường hợp này dấu chấm khớp với chữ số cuối cùng. Hãy thử '123'.match (/ (\ d +) ./) để xác minh.

(Vẫn) một trong những đoạn javascript dài hơn bao giờ hết ...
(Không được gán cho chuỗi 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

Bạn có thể vui lòng giải thích những gì /\d+./g,x=>không?
izlin

1
@izlin Tôi đã thêm một số lời giải thích cho câu trả lời
edc65

Tôi biết đây là một câu trả lời cũ, nhưng bạn có thể thay đổi eval('0b'+x)để '0b'+x-0tiết kiệm 4 byte.
Sản phẩm ETH

8

Bash + tiện ích linux phổ biến, 25 byte

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

giải thích dc

  • đẩy 2 lên ngăn xếp; bật và sử dụng làm cơ số đầu vào
  • đẩy chuỗi đầu vào để xếp chồng (tất cả các giá trị cùng một lúc)
  • Xác định macro đệ quy mđể:
    • bật, sau đó in giá trị dưới dạng ASCII
    • đẩy chiều sâu ngăn xếp để ngăn xếp
    • đẩy 0 để xếp
    • pop top 2 giá trị ngăn xếp; so sánh và gọi mmacro nếu ngăn xếp không trống
  • trùng lặp đầu ngăn xếp (định nghĩa vĩ mô)
  • bật và lưu macro để mđăng ký
  • bật và thực thi macro

Bởi vì chúng tôi đẩy toàn bộ chuỗi nhị phân lên ngăn xếp trước, khi chúng tôi bật từng giá trị, chúng tôi kết thúc chuỗi bị đảo ngược. Vì vậy, chúng tôi sử dụng các revtiện ích để sửa điều đó.

Ví dụ sử dụng:

$ 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: Không thấy câu trả lời PowerShell khác. Nhưng về cơ bản chỉ có một cách để giải quyết điều này.


7

C - 57 43 38/31

Phiên bản 38 byte:

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

Hoặc chỉ có 31 byte nếu s là một con trỏ:

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

Tôi không nghĩ rằng đây chính xác là cách sử dụng vòng lặp for và while ... nhưng nó hoạt động.


6

Bình 12 tháng 12

smCv+"0b"dPZ

Lưu ý rằng s không phải là biến hợp pháp trong Pyth, vì vậy tôi đã sử dụng Z thay thế.

Giải trình:

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

Thí dụ:

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

Thực tế là nó không sử dụng khoảng trắng trong định dạng (đây là nhìn vào Python của bạn) là một +1 chính
Pharap

@Pharap Vâng, một cách nhìn về Pyth là Python với tất cả các yếu tố khiến nó mất nhiều ký tự hơn, như khoảng trắng, dấu ngoặc đơn, mã thông báo nhiều ký tự, v.v.
isaacg 27/07/14

Tôi không biết Pyth, nhưng nó sẽ không lưu 4 ký tự để sử dụng id2thay cho v+"0b"d? Trong mọi trường hợp, điều này là không thể đọc được và mát mẻ.
DLosc

@DLosc Tôi đã thêm chức năng đó vào Pyth sau khi câu hỏi này được hỏi, phần lớn là do câu hỏi này. Nó sẽ ngắn hơn với Pyth ngày nay, nhưng Pyth ngày nay không được phép cho thử thách này.
isaacg

Tôi hiểu rồi. Tôi tự hỏi nếu nó có thể là một cái gì đó như thế.
DLosc

6

Mã máy x86 trên 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                                 |...!..|

Vì không có biến chuỗi thực trong mã máy (và đặc biệt, không có biến nào có tên " s"), tôi đã giải quyết cho stdin làm đầu vào.

Đầu vào 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)})

Vòng lặp đơn giản trên chuỗi nhị phân trong $ s. Phải bao gồm [chuyển đổi] giết điểm của tôi mặc dù.

EDIT: Thực sự chỉ có một cách để thực hiện điều này trong Powershell, wowie. Joey và tôi đều nhận được khá nhiều câu trả lời giống nhau khi làm việc độc lập!

Đầu vào:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

Đầu ra:

Hello World

1
Bạn có thể sử dụng toán tử phân chia đơn nguyên, lưu ba ký tự (tại đó câu trả lời của chúng tôi giống hệt nhau ... bất ngờ lớn ;-)).
Joey

@Joey Ohh, điểm tốt! Không thể tin rằng tôi đã bỏ lỡ điều đó. Bạn nhận được +1 từ tôi vì đã nắm bắt được điều đó, cảm ơn!
fuandon

5

Toán học, 52 byte

Ah, tên hàm đáng yêu của Mathicala

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

5

Perl 33 32

Chỉnh sửa: Giải pháp cập nhật, 32.

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

Giải pháp trước (33):

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

hoặc là

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

Kiểm tra:

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

Kiểm tra:

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

Giải trình:

                  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

Vỏ Python  44  40 ký tự

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

Cảm ơn sự giúp đỡ của Griffin .


'' .join (chr (int (x, 2)) cho x trong s.split ())
Griffin

4

APL (15)

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

Kiểm tra:

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

Giải trình:

  • ⍎s: đánh giá s, biến nó thành một mảng các số nguyên. Mảng được viết dưới dạng số cách nhau bởi khoảng trắng, vì vậy phần này sẽ phân tách s.
  • {... : cho từng yếu tố:
    • ⍕⍵: biến số trở lại thành một chuỗi
    • ⍎¨: đánh giá từng chữ số riêng lẻ, đưa ra một chuỗi bit
    • 2⊥: giải mã cơ sở 2, đưa ra các số
  • ⎕UCS: lấy ký tự cho mỗi số

Trừ khi có quy định khác, bạn nên đếm byte thay vì ký tự: codegolf.stackexchange.com/tags/code-golf/info :)
Averroes

1
@Averroes: bộ ký tự APL vừa vặn trong một byte có chỗ trống: frankenstein.dns.org.uk/~marinus/aplcharset.png
marinus

À, tôi không biết điều đó. Lỗi của tôi. Lấy làm tiếc!
Averroes

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 việc mã hóa có thể bỏ qua các số 0 đứng đầu do đó str_split($s,8)sẽ không hoạt động. foreach(explode(' ',$s)as$v)echo chr(bindec($v));sẽ hợp lệ nhưng tôi không có kế hoạch chỉnh sửa một trong những câu trả lời PPGC đầu tiên của mình mà rõ ràng là không thực sự chơi gôn. Dù sao cũng cảm ơn bạn
Christoph

4

Bacchus , 25 byte

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

Giải trình:

S,' 'j tách Chuỗi S bằng khoảng trống và chuyển đổi nó thành một khối (một số loại mảng).

:A= lấy Block trước và khẳng định nó với biến A.

(),A¨ cho mỗi phần tử trong A

Ö,2,10bĐọc phần tử hiện tại (đại diện bởi Ö) trong cơ sở 2 và chuyển đổi nó thành cơ sở 10.

:c lấy giá trị trước đó và in dưới dạng char



3

C - 63

Vì C không có trình chuyển đổi cơ sở 2 trong thư viện chuẩn: kiểm tra ở đây
chỉnh sửa: có, tôi thật quá ngu ngốc khi biết về nó

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

3

Chạy Brainfuck được mã hóa chiều dài, 49 byte

Vì không có biến trong Brainfuck, tôi chỉ sử dụng đầu vào và đầu ra tiêu chuẩn để thay thế.

32+nên được hiểu là 32 +s bởi trình thông dịch. Chỉ cần thay thế chúng bằng tay nếu trình thông dịch của bạn không hỗ trợ RLE.

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

Phiên bản mở rộng (không phải RLE): (91 byte)

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

Mã này giả định rằng EOF được mã hóa thành 0.

Giải trình

Bố cục sau đây được sử dụng:

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

Trường hợp xbyte ASCII được in, alà ký tự từ đầu vào tiêu chuẩn và flaglà 1 nếu alà khoảng trắng.

>,            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 Bởi vì mọi thứ nên có một triển khai brainfuck.
Pharap

"Chạy dài được mã hóa Brainfuck" là một ngôn ngữ riêng biệt thực sự? Tôi không thể tìm thấy một thông dịch viên.
mbomb007

3

Java 8: 60 byte

Sử dụng lambdas trong Java 8 (75 byte):

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

Và nếu bạn cho phép nhập tĩnh (mà một số ở đây đã sử dụng) thì đó là (61 byte):

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

Một phiên bản ngắn hơn một chút bằng cách sử dụng vòng lặp for (60 byte):

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

2
Cái gì, họ thực sự đã thay thế cho sự quái dị được gọi là lớp ẩn danh? Tuyệt vời.
xem

@Sieg có Java bây giờ cũng có lambdas / đóng cửa, nhưng nó chủ yếu là đường tổng hợp trên đầu các lớp ẩn danh ... (rõ ràng)
Roy van Rijn

3

Clojure 63 (hoặc 57)

Hàm All-Clojure:

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

Với sự can thiệp của Java:

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

Phiên 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$

Gì? Chúng tôi không có chức năng nhị phân đến thập phân ưa thích ở đây. Tự làm đi!

Tôi đang đếm dòng mới (mà tôi nghĩ là cần thiết để lấy if-then-other mà không có END IF) dưới dạng một byte, trên mỗi bài đăng meta này . Tôi không biết liệu QB64 trên Windows có chấp nhận tệp mã theo cách đó hay không. Có lẽ không có vấn đề gì nhiều.


2

Nút 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));});

Làm thế nào để bạn chạy nodejs với khả năng tương thích es6? mới nhất chúng ta vẫn không hỗ trợ chức năng lambda cho tôi
bebe

Các chức năng @bebe Mũi tên được triển khai trong v8 nhưng chúng chưa được tích hợp với nút. Tôi sẽ chỉnh sửa bài viết của mình.
cPu1

@ cPu1 họ làm việc cho tôi
tên người

2

JavaScript 111

Điều này thực hiện chuyển đổi số mà không có parseInt hoặc eval. Đọc chuỗi ngược và đếm bit, nó đặt bit x nếu là một. Khi tìm thấy một khoảng trắng, một số được chuyển đổi thành char và một số 0 mới được bắt đầu để thiết lập các 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 để thực hiện theo cách cũ - đã truyền cảm hứng cho tôi để viết phiên bản QBasic.
DLosc

Không hợp lệ, cần phải là một chức năng hoặc chương trình đầy đủ (một chương trình lấy đầu vào)
ASCII chỉ có


2

CJam, 11 byte

NS/{:~2bc}/

s không phải là một tên biến hợp pháp trong CJam, vì vậy tôi đã chọn N thay thế.

Hãy thử trực tuyến.

Chạy ví dụ

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

Làm thế nào nó hoạt động

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 nhập khẩu (?))

Đây là nỗ lực chơi gôn đầu tiên của tôi ở Haskell.

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

Bạn cần nhập Data.Char

cách sử dụng (tính bằng 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"

Giải trình:

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

Hy vọng rằng tôi đã tuân theo các quy ước chấm điểm chính xác về nhập khẩu. Vui lòng chỉnh sửa trong một chỉnh sửa nếu tôi không. Tôi đã xử lý ": m + Data.Char" cần thiết để nhập vào ghci là 13.
ballesta25

1

GNU Sed, 19 byte

Lấy cảm hứng từ một câu trả lời tuyệt vời @Digital Trauma.

Chơi gôn

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

Kiểm tra

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 (không cạnh tranh)

smCid2c

Lấy đầu vào dưới dạng chuỗi.

Thử nó!


Đánh dấu là không cạnh tranh vì ngôn ngữ mới hơn thách thức.
mbomb007

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.