バイナリ暗号化


11

これはxkcd#153に基づいています。

2つのパラメーターをとるプログラムまたは名前付き関数を作成します。各パラメーターは、文字列、またはバイトまたは文字のリストまたは配列です。2番目のパラメーターには、lrfu(または同等のASCIIバイト)からの文字のみが含まれます。これは、最初のパラメーターで表されるビットシーケンスで実行される一連の命令として解釈される必要があります。

実行される処理は、次と同等である必要があります。

  1. 最初のパラメーターを各文字のビットを連結して形成される単一のビット文字列に変換します(7ビットASCII、8ビット拡張ASCII、または標準Unicodeエンコードのいずれかとして解釈されます)。たとえば、最初のパラメーターが"AB"次にある場合、これは10000011000010(7ビット)、0100000101000010(8ビットまたはUTF-8)、、00000000010000010000000001000010または01000001000000000100001000000000(2つのエンディアンのUTF-16)などのいずれかになります。
  2. 2番目のパラメーターの各文字について、順番に、対応する命令を実行します。
    • lビット列を左に回転します。例えばに10000011000010なり00000110000101ます。
    • rビット列を右に回転します。例えばに10000011000010なり01000001100001ます。
    • fビット列の各ビットを反転(または反転)します。例えばに10000011000010なり01111100111101ます。
    • uビット列を反転します。例えばに10000011000010なり01000011000001ます。
  3. ビット文字列をビットごとに1文字を使用するASCII文字列に変換します。例えばに10000011000010なり"10000011000010"ます。これは、7/8ビットのすべてのセットに文字が割り当てられているわけではないためです。

例(Python):

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

それはターン"b"の8ビットASCIIバイナリ表現に01100010、それが正しい(回転00110001)(各ビットを反転させ11001110)、それを(反転します01110011)。

柔軟性

その他の文字は文字の代わりに使用することができるlrf、そしてu、彼らは明確に文書化されなければなりません。

スコアボード

次のコードスニペットを作成してくれた@Optimizerに感謝します。使用するには、[コードスニペットを表示]をクリックし、一番下までスクロールして[►コードスニペットを実行]をクリックします。


3
2番目のパラメーターは何ですか?できます"rrfrburb"か?また、ビットをシフトまたはリバースするとき、個々の文字ごとに、または文字列全体に対してそれを行いますか?より多くのテストケースはそれを明確にするでしょう。
-xnor

1
シフトまたはローテーションを意味しますか?Cを左にシフトすると、左端のビットが失われ、右端のビットがゼロになります。符号なしの数値の右シフトの場合、逆になります。符号付きの数値の場合、負の数値でシフトインされるものに対して普遍的に定義された動作があるかどうかはわかりません(0または1ですか?)回転します。
レベルリバーセント


2

1
@KSFTノーと言わなければならないと思う。結合して文字列にします。

回答:


1

CJam、34 32バイト

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

手順には次の文字を使用します。

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

入力はSTDINから取得され、最初の行に単語があり、2行目に命令文字列があります。

ここでテストしてください。

説明

ビット文字列を取得することは、文字コードをベース256の数字として解釈すること(およびそのベース2表現を取得すること)だけです。トリッキーなことは、後者のベース変換では、結果の左側に0が埋め込まれないことです。したがって、最初の入力に先頭の1を追加し、その1をバイナリ表現で再度分割します。入力された場合、一例としてab、私は、配列にそのターン[1 'a 'b]であり、ベース256として(文字は自動的に文字コードに変換される)と解釈90466されており、ベース2および[1 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0]。今、その先頭1を削除するだけで、探しているビットストリームが手に入ります。

それが、コードのこの部分が行うことです。

1l+256b2b1>

次に、命令のリストを読み取り、命令文字列の各文字に対してブロックを実行します。

l{...}/

まず最初に行うには、文字と実際の整数を評価することである012または3。本当のゴルフの魔法...命令に応じて、操作を実装する短いコードを実行します。

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

これらをブロックの配列に格納し、実行する適切なブロックを選択できますが、実際には文字列でエンコードする方が短くなります。

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

まず、命令に関連付けられた整数を使用して、文字列の先頭を切り取ります。したがって、左回転の場合、文字列は変更されず、右回転の場合、最初の文字は破棄されます。次に、文字列の最初の文字から4文字ごとにを選択します4%。4つのコードスニペットが文字列全体にどのように分散されているかに注目してください。最後に、文字列をとしてコードとして評価します~

ビット文字列は、プログラムの最後に自動的に印刷されます。


なぜ1m<ではなく(+?あなたは数字ではなく配列に取り組んでいますよね?
ピーターテイラー

@Peterまあ、ありがとう。後で修正します。
マーティンエンダー

2

CJam、34バイト

CJamの別のアプローチ。

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

入力テキストは1行目にあり、指示は2行目にあります。

手順:

)        Rotate left.
(        Rotate right.
 (space) Flip.
~        Reverse.

1
これはかなり賢いです。f~しかし、実装されていないのは残念ですね。;)
マーティン・エンダー

2

Pyth 33

jku@[+eGPG+tGhG_Gms!dG)sHwsmjCk2z

用途:

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

Pyth GitHub

こちらからオンラインでお試しください。

これは、文字列を最初の引数として使用し、コマンドの文字列を2番目の引数として使用するプログラムです。オンライン版では、次のように文字列を改行で区切ってください:

AbC
0321

説明:

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

私がまったく絞り込めなかったもの:Pyth は前の値と次の値にreduce自動的に使用GHます。


あなたのタッチを失いますか?CJamより1バイト短い?
オプティマイザー

@Optimizer実際には、同じ手順を使用してそれを打ち負かすことができます。しかし、チャレンジでは「の代わりに他の文字を使用することもできますlrfuが、それらは明確に文書化する必要があります。」(強調鉱山)
マーティンエンダー

1

スカラ-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

1

Matlab(166バイト)

これはabcdlrfuそれぞれの代わりに文字を使用します。

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';

ここでスペースを節約するために使用されるいくつかのトリック:

  • 使用するabcd文字は、私は引くことができます97一度、その後の文字になります0123。これにより、switch- case句のスペースが節約されます。
  • circshift1文字の匿名関数として定義すると、2回使用されるため、スペースも節約できます。
  • 以来、Dから構成'0'し、'1'文字(ASCIIコード4849)、ステートメントがD=char(97-D)間の反転に対応'0'し、'1'値。これ97は上記の説明とは関係がないことに注意してください。
  • transposeの'代わりに複素共役転置が使用され.'ます。

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)

0

C#、418バイト

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

フォーマット済み:

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

0

J、164

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

フォーマット済み:

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.

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

0

JavaScript(E6)、163 167

入力の柔軟性、2つの配列パラメーターを持つ名前付き関数を完全に使用します。

  • 最初のパラメーター、7ビット文字コードに対応するバイトの配列
  • 2番目のパラメーター、ASCII文字「F」、「L」、「R」、「U」に対応するバイトの配列-> 70、76、82、85

関数は、「1」と「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('')

f("b", "rfu")翻訳F([98],[82,70,85])は、結果は0111001

なお、 JavaScriptであるので、はるかに長い文字列を使用して!バイト数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('')

F("b", "RFU")、結果は0111001再び


0

ルビー、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}}

かなり簡単です。文字をトラフでループしs、それらのいずれかに対してアクションを実行します。


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]))

アプローチの私の答えと同様に、すべての文字列のリストを作成し、reduceを使用して繰り返し処理する命令文字列の値に基づいてインデックスを作成します。

用途:

0  ->  Rotate left
1  ->  Rotate right
2  ->  Reverse order
3  ->  Invert bits
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.