Enkripsi biner

11

Ini didasarkan pada xkcd # 153 .

Buat program atau fungsi bernama yang mengambil 2 parameter, masing-masing adalah string atau daftar atau array byte atau karakter. Parameter kedua hanya akan berisi karakter yang diambil dari lrfu(atau byte ASCII yang setara). Ini harus ditafsirkan sebagai serangkaian instruksi yang harus dilakukan pada urutan bit yang diwakili oleh parameter pertama.

Pemrosesan yang dilakukan harus setara dengan yang berikut:

  1. Konversikan parameter pertama menjadi bitstring tunggal yang dibentuk dengan menggabungkan bit dari masing-masing karakter (ditafsirkan sebagai salah satu dari ASCII 7-bit, ASCII yang diperluas 8-bit, atau pengkodean Unicode standar). Misalnya jika parameter pertama adalah "AB"maka ini akan menjadi salah satu 10000011000010(7-bit), 0100000101000010(8-bit atau UTF-8) 00000000010000010000000001000010,, atau 01000001000000000100001000000000(UTF-16 dalam dua endiannesses), dll.
  2. Untuk setiap karakter di parameter kedua, secara berurutan, jalankan instruksi yang sesuai:
    • lmemutar bitstring ke kiri. Misalnya 10000011000010menjadi 00000110000101.
    • rmemutar bitstring ke kanan. Misalnya 10000011000010menjadi 01000001100001.
    • fmembalik (atau membalikkan) setiap bit dalam bitstring. Misalnya 10000011000010menjadi 01111100111101.
    • umembalikkan bitstring. Misalnya 10000011000010menjadi 01000011000001.
  3. Konversi bitstring menjadi string ASCII yang menggunakan satu karakter per bit. Misalnya 10000011000010menjadi "10000011000010". Ini karena tidak semua set 7/8 bit memiliki karakter yang ditugaskan padanya.

Contoh (dalam Python):

>>> f("b", "rfu")
01110011

Ia berubah "b"menjadi representasi biner ASCII 8-bit 01100010, memutarnya dengan benar ( 00110001), membalik setiap bit ( 11001110), dan membalikkannya ( 01110011).

Fleksibilitas

Karakter lain dapat digunakan sebagai pengganti karakter l, r, f, dan u, tetapi mereka harus jelas didokumentasikan.

Papan angka

Terima kasih kepada @Optimizer untuk membuat cuplikan kode berikut. Untuk menggunakan, klik "Tampilkan cuplikan kode", gulir ke bawah dan klik "► Jalankan cuplikan kode".


sumber
3
Apa yang bisa menjadi parameter kedua? Bisakah itu terjadi "rrfrburb"? Juga, ketika seseorang menggeser atau membalikkan bit, apakah ia melakukannya untuk setiap huruf individual, atau string secara keseluruhan? Lebih banyak kasus uji akan membuatnya lebih jelas.
xnor
1
Apakah maksud Anda menggeser atau memutar? pergeseran kiri dalam C akan menghasilkan bit paling kiri hilang dan bit paling kanan menjadi nol. Untuk pengalihan hak pada nomor yang tidak ditandatangani, kebalikannya terjadi. Untuk nomor yang ditandatangani, saya tidak yakin apakah ada perilaku yang ditetapkan secara universal untuk apa yang digeser ke nomor negatif (apakah 0 atau 1?) Either way, informasi selalu hilang ketika pergeseran dilakukan, yang tidak terjadi untuk memutar.
Level River St
2
@ flawr, saya tidak berpikir itu akan memiliki keuntungan di atas kemampuan yang ada untuk mencari 'xkcd'
Peter Taylor
1
@KSFT Saya pikir saya harus mengatakan tidak untuk itu. Buat string dengan bergabung.

Jawaban:

1

CJam, 34 32 byte

1l+256b2b1>l{~"11W:mm%!<>">4%~}/

Ini menggunakan karakter berikut untuk instruksi:

0: left rotation
1: right rotation
2: reverse
3: flip

Input diambil dari STDIN dengan kata di baris pertama dan string instruksi di baris kedua.

Uji di sini.

Penjelasan

Mendapatkan bit string sebenarnya hanya masalah menafsirkan kode karakter sebagai digit nomor basis-256 (dan mendapatkan representasi basis-2). Yang sulit adalah bahwa konversi basis yang terakhir tidak akan membuahkan hasil dengan 0s di sebelah kiri. Oleh karena itu, saya menambahkan 1 yang memimpin ke input awal, dan kemudian membagi 1 lagi di representasi biner. Sebagai contoh, jika inputnya adalah ab, saya mengubahnya menjadi array [1 'a 'b], menafsirkannya sebagai base-256 (karakter secara otomatis dikonversi ke kode karakter), yang mana 90466dan ke basis-2, yang mana [1 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0]. Sekarang jika saya hanya menghapus yang memimpin 1saya punya bitstream yang saya cari.

Itulah yang dilakukan oleh bagian kode ini:

1l+256b2b1>

Sekarang saya membaca daftar instruksi dan mengeksekusi blok untuk setiap karakter dalam string instruksi:

l{...}/

Hal pertama yang harus dilakukan adalah untuk mengevaluasi karakter dan bilangan bulat yang sebenarnya 0, 1, 2atau 3. Sekarang keajaiban golf yang sebenarnya ... tergantung pada instruksi saya ingin menjalankan sepotong kode pendek yang mengimplementasikan operasi:

Integer:  Code  Operation
0         1m<   "Left rotation";
1         1m>   "Right rotation";
2         W%    "Reverse";
3         :!    "Flip each bit";

Saya bisa menyimpan ini dalam array blok dan memilih blok yang tepat untuk dijalankan, tetapi menyandikannya dalam string sebenarnya lebih pendek:

"11W:mm%!<>">4%~

Pertama, saya menggunakan asosiasi integer dengan instruksi untuk memotong awal string. Jadi untuk rotasi kiri, string tidak berubah, untuk rotasi kanan karakter pertama dibuang dan seterusnya. Lalu saya memilih setiap karakter keempat dari string, mulai dari yang pertama, dengan 4%. Perhatikan bagaimana keempat cuplikan kode didistribusikan di seluruh string. Akhirnya saya hanya mengevaluasi string sebagai kode ~.

String bit dicetak secara otomatis di akhir program.

Martin Ender
sumber
Kenapa 1m<bukan (+? Anda sedang bekerja pada array daripada angka, bukan?
Peter Taylor
@ Peter oh benar, terima kasih. Saya akan memperbaikinya nanti.
Martin Ender
2

CJam, 34 byte

Pendekatan lain dalam CJam.

1l+256b2b1>l_S/,1&@f=_,,@f{W%~}\f=

Teks input ada di baris pertama dan instruksi ada di baris kedua.

Instruksi:

)        Rotate left.
(        Rotate right.
 (space) Flip.
~        Reverse.
jimmy23013
sumber
1
Ini cukup pintar. Sayang sekali f~tidak diterapkan, bukan? ;)
Martin Ender
2

Pyth 33

jku@[+eGPG+tGhG_Gms!dG)sHwsmjCk2z

Penggunaan:

0    : rotate right
1    : rotate left
2    : reverse order
3    : flip values

Pyth github

Cobalah online di sini.

Ini adalah program yang menggunakan string sebagai argumen pertama dan string perintah sebagai argumen kedua. Dalam versi online, Anda harus memberikan string yang dipisahkan oleh baris baru, seperti:

AbC
0321

Penjelasan:

                                    : z=input() (implicit)
jk                                  : join("", ...)
  u@[                 )sHw          : reduce(select from [...] the value at int(H), input(), ...)
     +eGPG                          : [ G[-1] + G[:1],
          +tGhG                     : G[1:] + G[1],
               _G                   : G[::-1],
                 ms!dG              : map(lambda d: int(not(d)), G) ]
                          smjCk2z   : first arg = sum(map(lambda k:convert_to_base(ord(k),2),z)

Sesuatu yang tidak bisa saya tekan: Pyth reducesecara otomatis menggunakan Guntuk nilai sebelumnya, dan Huntuk nilai berikutnya.

FryAmTheEggman
sumber
Kehilangan sentuhan Anda? Hanya 1 byte lebih pendek dari CJam?
Pengoptimal
@ Opptizer Sebenarnya, saya bisa mengalahkannya dengan menggunakan instruksi yang sama. Tetapi saya tidak berpikir ini akan valid karena tantangan mengatakan " Surat - surat lain mungkin digunakan sebagai pengganti lrfu, tetapi mereka harus didokumentasikan dengan jelas." (penekanan saya)
Martin Ender
1

Scala - 192

def f(i:String,l:String)=(i.flatMap(_.toBinaryString).map(_.toInt-48)/:l){
case(b,'l')⇒b.tail:+b.head
case(b,'r')⇒b.last+:b.init
case(b,'f')⇒b.map(1-_)
case(b,'u')⇒b.reverse}.mkString
gilad hoch
sumber
1

Matlab (166 byte)

Ini menggunakan huruf abcdbukan lrfumasing - masing.

function D=f(B,C)
D=dec2bin(B,8)';
D=D(:);
g=@circshift;
for c=C
switch c-97
case 0
D=g(D,-1);
case 1
D=g(D,1);
case 2
D=char(97-D);
case 3
D=flipud(D);
end
end
D=D';

Beberapa trik yang digunakan di sini untuk menghemat ruang:

  • Menggunakan abcdhuruf memungkinkan saya kurangi 97sekali, dan kemudian huruf menjadi 0, 1, 2, 3. Ini menghemat ruang dalam switch- caseklausa.
  • Mendefinisikan circshiftsebagai fungsi anonim satu huruf juga menghemat ruang, karena digunakan dua kali.
  • Karena Dterdiri dari '0'dan '1'karakter (kode ASCII 48dan 49), pernyataan tersebut D=char(97-D)sesuai dengan inversi antara '0'dan '1'nilai - nilai. Perhatikan bahwa ini 97tidak ada hubungannya dengan yang disebutkan di atas.
  • Complex-conjugate transpose 'digunakan sebagai pengganti transpose .'.
Luis Mendo
sumber
0

Python 2 - 179

b="".join([bin(ord(i))[2:]for i in input()])
for i in input():b=b[-1]+b[:-1]if i=="r"else b[1:]+b[0]if i=="l"else[str("10".find(j))for j in b]if i=="f"else b[::-1]
print"".join(b)
KSFT
sumber
0

C #, 418 byte

using System;using System.Collections.Generic;using System.Linq;class P{string F(string a,string o){var f=new Dictionary<char,Func<string,IEnumerable<char>>>{{'l',s=>s.Substring(1)+s[0]},{'r',s=>s[s.Length-1]+s.Substring(0,s.Length-1)},{'u',s=>s.Reverse()},{'f',s=>s.Select(c=>(char)(97-c))}};return o.Aggregate(string.Join("",a.Select(c=>Convert.ToString(c,2).PadLeft(8,'0'))),(r,c)=>new string(f[c](r).ToArray()));}}

Diformat:

using System;
using System.Collections.Generic;
using System.Linq;

class P
{
    string F(string a, string o)
    {
        // define string operations
        var f = new Dictionary<char, Func<string, IEnumerable<char>>>
        {
            {'l', s => s.Substring(1) + s[0]},
            {'r', s => s[s.Length - 1] + s.Substring(0, s.Length - 1)},
            {'u', s => s.Reverse()},
            {'f', s => s.Select(c => (char) (97 - c))}
        };
        // for each operation invoke f[?]; start from converted a
        return o.Aggregate(
            // convert each char to binary string, pad left to 8 bytes and join them
            string.Join("", a.Select(c => Convert.ToString(c, 2).PadLeft(8, '0'))),
            // invoke f[c] on result of prev operation
            (r, c) => new string(f[c](r).ToArray())
        );
    }
}
Krzysztof
sumber
0

J, 164

([: >@:}. (([: }. >&{.) ; >@:{.@:>@:{. 128!:2 >@:}.)^:({.@:$@:>@:{.))@:(>@:((<;._1 ' 1&|."1 _1&|."1 -. |."1') {~ 'lrfu' i. 0&({::)@:]) ; ;@:([: (8$2)&#: a. i. 1&({::)))

Diformat:

nextop=:([: }. >&{.)
exec=: (>@:{.@:>@:{.) apply"1 >@:}.
times=: ({.@:$@:>@:{.)
gapply=: [: >@:}. (nextop ; exec)^:(times) f.

tobin=: ;@:([: (8#2)&#:(a.i.1&{::))
g=:'1&|.';'_1&|.';'-.';'|.'
tog =:  g {~ ('lrfu' i. 0&{::@:])
golf=: gapply @: (>@:tog;tobin)  f.

Contoh

golf ('rfu';'b')
0 1 1 1 0 0 1 1


golf ('lruuff';'b')
0 1 1 0 0 0 1 0

(8#2)#: 98
0 1 1 0 0 0 1 0

golf ('lruuff';'AB')
0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0

tobin '';'AB'
0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0
joebo
sumber
0

JavaScript (E6), 163 167

Sepenuhnya menggunakan fleksibilitas input, fungsi bernama dengan 2 parameter array.

  • Parameter pertama, array byte yang terkait dengan kode karakter 7 bit
  • Parameter kedua, larik byte yang sesuai dengan karakter ascii 'F', 'L', 'R', 'U' -> 70, 76, 82, 85

Fungsi mengembalikan string karakter yang terdiri dari '1' dan '0'

F=(a,s,r='')=>
  a.map(c=>r+=(128|c).toString(2).slice(-7))-
  s.map(c=>a=c<71?a.map(c=>1-c):c<77?a.concat(a.shift):c<83?[a.pop(),...a]:a.reverse(),a=[...r])
  ||a.join('')

Contoh f("b", "rfu") terjemahkan ke F([98],[82,70,85]), hasilnya adalah0111001

Catatan menggunakan string karakter jauh lebih lama di javascript! Jumlah byte 186

F=(a,s,r='')=>
  [for(c of a)r+=(128|c.charCodeAt()).toString(2).slice(-7)]-
  [for(c of(a=[...r],s))a=c<'G'?a.map(c=>1-c):c<'M'?a.concat(a.shift):c<'S'?[a.pop(),...a]:a.reverse()]
  ||a.join('')

Contoh F("b", "RFU") , hasilnya 0111001lagi

edc65
sumber
0

Ruby, 151

f=->i,s{s.chars.inject(i.unpack("B*")[0]){|a,c|
a.reverse! if c==?u
a.tr!"01","10" if c==?f
a<<a.slice!(1..-1) if c==?l
a<<a.slice!(0..-2) if c==?r
a}}

Cukup mudah. Loop melalui karakter dalam sdan melakukan suatu tindakan untuk mereka

britishtea
sumber
0

Python 2, 142

j="".join
f=lambda S,I:reduce(lambda s,i:[s[1:]+s[0],s[-1]+s[:-1],s[::-1],j([`1^int(c)`for c in s])][int(i)],I,j([bin(ord(c))[2:]for c in S]))

Mirip dengan jawaban pyth saya dalam pendekatan: Saya membangun daftar semua string dan indeks ke dalamnya berdasarkan nilai dari string instruksi yang saya iterate menggunakan pengurangan.

Penggunaan:

0  ->  Rotate left
1  ->  Rotate right
2  ->  Reverse order
3  ->  Invert bits
FryAmTheEggman
sumber