二进制加密


11

这是基于xkcd#153的

制作一个带有2个参数的程序或命名函数,每个参数是一个字符串或字节或字符的列表或数组。第二个参数将仅包含从中提取的字符lrfu(或等效的ASCII字节)。应该将其解释为要对由第一参数表示的位序列执行的一系列指令。

执行的处理必须等同于以下内容:

  1. 将第一个参数转换为通过串联每个字符的位组成的单个位串(解释为7位ASCII,8位扩展ASCII或标准Unicode编码之一)。例如,如果第一个参数是"AB"那么这将是一个10000011000010(7位),0100000101000010(8位或UTF-8),0000000001000001000000000100001001000001000000000100001000000000(UTF-16在这两个字节排列顺序)等。
  2. 对于第二个参数中的每个字符,依次执行相应的指令:
    • l将位串左移一位。例如10000011000010变为00000110000101
    • r将位串右移一位。例如10000011000010变为01000001100001
    • f翻转(或反转)位串中的每个位。例如10000011000010变为01111100111101
    • u反转位串。例如10000011000010变为01000011000001
  3. 将位字符串转换为ASCII字符串,每位使用一个字符。例如10000011000010变为"10000011000010"。这是因为并非所有7/8位的集合都分配有一个字符。

示例(在Python中):

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

它变成"b"8位ASCII二进制表示形式01100010,向右旋转(00110001),翻转每个位(11001110),然后反转(01110011)。

灵活性

其它字符可以是用来代替字符lrf,和u,但他们必须清楚地记录在案。

计分板

感谢@Optimizer创建以下代码段。要使用,请单击“显示代码段”,滚动到底部,然后单击“►运行代码段”。


3
第二个参数是什么?可以"rrfrburb"吗?另外,当一个移位或反转位时,是针对每个单独的字母还是整个字符串执行一个操作?更多的测试案例将使其更加清晰。
xnor 2015年

1
你是说移位还是旋转?C的左移将导致最左边的位丢失并且最右边的位变为零。对于无符号数字的右移,则相反。对于带符号的数字,我不确定对于负数移入的内容是否存在通用定义的行为(是0还是1?),无论哪种方式,执行移位时总是会丢失信息,事实并非如此。旋转。
级圣河


2
@flawr,我认为与现有的搜索“ xkcd”功能
Peter Taylor

1
@KSFT我想我不得不对此说不。通过连接使其成为字符串。

Answers:


1

CJam,34 32字节

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

它使用以下字符进行说明:

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

输入来自STDIN,第一行是单词,第二行是指令字符串。

在这里测试。

说明

获取位字符串实际上只是将字符代码解释为以256为基数的数字(并获得以2为基数的表示形式)的问题。棘手的事情是,后者的基本转换不会在结果的左侧填充0。因此,我将一个前导1添加到初始输入中,然后在二进制表示形式中再次将其拆分为1。例如,如果输入为,则将其ab转换为数组[1 'a 'b],将其解释为base-256(字符自动转换为字符代码)90466和,以base-2表示[1 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0]。现在,如果我只是删除该引导线,则将1获得所需的比特流。

这就是这段代码的作用:

1l+256b2b1>

现在,我阅读了指令列表,并为指令字符串中的每个字符执行了一个块:

l{...}/

要做的第一件事是评估的特点和实际整数0123。现在是真正的高尔夫魔术……根据指令,我想运行一小段实现操作的代码:

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

我可以将它们存储在块数组中,然后选择要运行的块,但是将它们编码为字符串实际上会更短:

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

首先,我将整数关联与指令一起使用来分割字符串的开头。因此,对于左旋转,字符串保持不变,对于右旋转,第一个字符被丢弃,依此类推。然后,我从字符串的第一个开始选择第四个字符,从4%。请注意,这四个代码段是如何在整个字符串中分布的。最后,我只是使用来评估字符串作为代码~

位字符串将在程序末尾自动打印。


为什么1m<而不是(+?您正在处理数组而不是数字,不是吗?
彼得·泰勒

@Peter哦,对了,谢谢。稍后再解决。
马丁·恩德

2

CJam,34个字节

CJam中的另一种方法。

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

输入文本在第一行,说明在第二行。

说明:

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

1
这很聪明。遗憾的f~是没有实现,不是吗?;)
Martin Ender 2015年

2

腐霉菌33

jku@[+eGPG+tGhG_Gms!dG)sHwsmjCk2z

用途:

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

Pyth github

在这里在线尝试。

这是一个将字符串作为第一个参数,将命令字符串作为第二个参数的程序。在在线版本中,应使用换行符分隔字符串,如下所示:

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自动使用G上一个值和H下一个值。


松动您的手感?比CJam短1个字节吗?
Optimizer

@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字节)

这使用字母abcd代替lrfu

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子句中的空间。
  • 定义circshift为一个字母的匿名函数还可以节省空间,因为它被使用了两次。
  • 由于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),163167

充分利用输入灵活性,一个具有2个数组参数的命名函数。

  • 第一个参数,对应于7位字符代码的字节数组
  • 第二个参数,对应于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]))

类似于我在方法中的pyth答案:我建立了所有字符串的列表,并根据我使用reduce进行迭代的指令字符串的值对其进行索引。

用途:

0  ->  Rotate left
1  ->  Rotate right
2  ->  Reverse order
3  ->  Invert bits
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.