所以,我碰巧注意到last.fm正在我的地区招聘,因为我认识一些在 那里工作的人,但我申请了.
但我想我最好先看一下目前的工作人员.
那个页面上的每个人都有一个可爱/聪明/愚蠢的背带,比如"生命不是一千倍太短,我们无法忍受自己?".事实上,这是非常有趣的,直到我达到这个:
perl -e'print+pack+q,c*,,map$.+=$_,74,43,-2,1,-84, 65,13,1,5,-12,-3, 13,-82,44,21, 18,1,-70,56, 7,-77,72,-7,2, 8,-6,13,-70,-34'
Run Code Online (Sandbox Code Playgroud)
我无法抗拒粘贴到我的终端(也许是一种愚蠢的事情),但它打印出来:
只是另一个Last.fm黑客,
我认为弄清楚Perl单线程如何工作会相对容易.但我真的无法理解文档,我不知道Perl,所以我甚至不确定我是否正在阅读相关文档.
所以我尝试修改数字,这让我无处可去.所以我认为这真的很有趣,值得一试.
所以,"它是如何工作的"有点模糊,我的问题主要是,
那些数字是多少?为什么有负数和正数,否定性或积极性是否重要?
运营商的组合是+=$_做什么的?
在pack+q,c*,,做什么?
Gil*_*il' 29
这是"Just another Perl hacker"的一个变种,一个Perl meme.随着JAPH的到来,这个相对温和.
您需要做的第一件事是弄清楚如何解析perl程序.它缺少函数调用的括号,+并以有趣的方式使用类似于引号的运算符.原来的程序是这样的:
print+pack+q,c*,,map$.+=$_,74,43,-2,1,-84, 65,13,1,5,-12,-3, 13,-82,44,21, 18,1,-70,56, 7,-77,72,-7,2, 8,-6,13,-70,-34
Run Code Online (Sandbox Code Playgroud)
pack是一个函数,而print并map是列表操作.无论哪种方式,紧跟一个加号的函数或非空运算符名称都不能+用作二元运算符,因此+开头的两个符号都是一元运算符.手册中描述了这种奇怪之处.
如果我们添加括号,使用块语法map,并添加一些空格,我们得到:
print(+pack(+q,c*,,
map{$.+=$_} (74,43,-2,1,-84, 65,13,1,5,-12,-3, 13,-82,44,21,
18,1,-70,56, 7,-77,72,-7,2, 8,-6,13,-70,-34)))
Run Code Online (Sandbox Code Playgroud)
下一个棘手的问题是q这里是q 类似引用的运算符.它通常用单引号编写:
print(+pack(+'c*',
map{$.+=$_} (74,43,-2,1,-84, 65,13,1,5,-12,-3, 13,-82,44,21,
18,1,-70,56, 7,-77,72,-7,2, 8,-6,13,-70,-34)))
Run Code Online (Sandbox Code Playgroud)
请记住,一元加号是一个无操作(除了强制标量上下文),所以现在应该看起来更熟悉了.这是对pack函数的调用,格式c*为"任意数量的字符,由当前字符集中的数字指定".另一种写这个的方法是
print(join("", map {chr($.+=$_)} (74, …, -34)))
Run Code Online (Sandbox Code Playgroud)
该map函数按顺序将提供的块应用于参数列表的元素.对于每个元素,$_将其设置为元素值,并且map调用的结果是通过对连续元素执行块返回的值列表.编写这个程序的更长的方法是
@list_accumulator = ();
for $n in (74, …, -34) {
$. += $n;
push @list_accumulator, chr($.)
}
print(join("", @list_accumulator))
Run Code Online (Sandbox Code Playgroud)
该$.变量包含运行的总数.选择数字,使得运行总数是作者想要打印的字符的ASCII代码:74 = J,74 + 43 = 117 = u,74 + 43-2 = 115 = s等.它们是负的还是正的,具体取决于是否每个字符都以ASCII顺序在前一个字符之前或之后.
对于您的下一个任务,请解释此JAPH(由EyesDrop生成).
''=~('(?{'.('-)@.)@_*([]@!@/)(@)@-@),@(@@+@)'
^'][)@]`}`]()`@.@]@%[`}%[@`@!#@%[').',"})')
Run Code Online (Sandbox Code Playgroud)
不要在生产代码中使用任何此类代码.
Ulr*_*gel 22
这背后的基本思想非常简单.您有一个包含字符的ASCII值的数组.为了使事情变得更复杂,你不要使用绝对值,而是使用相对的值,除了第一个.因此,我们的想法是将特定值添加到前一个值,例如:
Jus尽管$.在Perl中是一个特殊的变量,但在这种情况下它并不意味着什么特别的东西.它仅用于保存以前的值并添加当前元素:
map($.+=$_, ARRAY)
Run Code Online (Sandbox Code Playgroud)
基本上它意味着将当前列表元素($_)添加到变量中$..这将返回一个新数组,其中包含新句子的正确ASCII值.
qPerl中的函数用于单引号的文字字符串.例如,你可以使用像
q/Literal $1 String/
q!Another literal String!
q,Third literal string,
Run Code Online (Sandbox Code Playgroud)
这意味着pack+q,c*,,基本上pack 'c*', ARRAY.的c*在改性剂pack解释该值作为字符.例如,它将使用该值并将其解释为字符.
它基本归结为:
#!/usr/bin/perl
use strict;
use warnings;
my $prev_value = 0;
my @relative = (74,43,-2,1,-84, 65,13,1,5,-12,-3, 13,-82,44,21, 18,1,-70,56, 7,-77,72,-7,2, 8,-6,13,-70,-34);
my @absolute = map($prev_value += $_, @relative);
print pack("c*", @absolute);
Run Code Online (Sandbox Code Playgroud)