首先,在 C(和 C++)中k[pointer]
and pointer[k]
意思完全相同,即*(k + pointer
) and *(pointer + k)
, 分别。代码混淆器通常似乎喜欢使用第一个版本,因为很多人发现它不寻常。但相当明显的是pointer + k
and k + pointer
是相同的计算。
代码片段中的另一个小转移是使用
pointer-~!(something)
这与
pointer + (something == 0 ? 2 : 1)
这是如何运作的:
The !
运算符将任何 true(非零)值转换为 0,将 false (0) 值转换为布尔 true (1):
!something: something == 0 ? 1 : 0
The ~
运算符是按位取反的,所以它变成0
转化为全 1 位组成的数,即-1
and 1
转化为除最后一位外全部为 1 的数,即-2
。请参阅维基百科文章二进制补码 http://en.wikipedia.org/wiki/Two%27s_complement.
~!something: something == 0 ? -2 : -1
从某物中减去它与添加负数相同(a - -b == a + b
)
a-~!something: something == 0 ? a + 2 : a + 1
Finally
1[a-~!something]: something == 0 ? a[3] : a[2]
因此,它根据某些计算是否为零来选择第二个或第三个命令行参数。
所以现在我们需要破译“一些计算”。我们从类型双关运算符开始*(T *)(pointer)
, 在这种情况下*(int*)(char*)
,读出指针指向的任何内容,就好像它是一个T
。所以在这种情况下,它读取第一个sizeof(int)
字符来自1[acters]
-- 也就是说,从第一个命令行参数开始(argv[1]
)——就好像它们是整数的内部表示一样。这将根据每位总统姓氏的前四个字符将其编码为整数。
虽然美国历史上曾出现过多次总统姓氏重复的情况,但只要两位同名总统属于同一个政党,就不成问题。
其中一对父子约翰·亚当斯 (John Adams, Jr.)(联邦党人)和约翰·昆西·亚当斯 (John Quincy Adams)(作为联邦党人当选参议员,作为民主共和党人当选总统)因在第一个有效投票之前被淘汰总统(富兰克林·皮尔斯),老哈里森(威廉·亨利,辉格党人)也是如此,他的孙子本杰明被选为共和党人。乔治·H·W·布什 (George H.W.和乔治·W·布什都是共和党人。两位约翰逊,安德鲁和林登贝恩斯(据我所知,彼此没有亲属关系)都是民主党人。
这样就只剩下两位罗斯福了,西奥多(共和党)和富兰克林·德拉诺(民主党)。两位罗斯福总统的曾曾曾祖父是约翰内斯和雅各布斯兄弟,他们是罗斯福总统的儿子。尼古拉斯·罗斯福 http://en.wikipedia.org/wiki/Nicholas_Roosevelt_%281658%E2%80%931742%29(或尼古拉斯·范·罗森维尔特)(1658-1742 年)和荷兰移民克拉斯·马尔滕森·范·罗森维尔特的孙子,使他们成为第五代堂兄弟。然而,通过西奥多的侄女、罗斯福总统的妻子埃莉诺·罗斯福,两位总统之间的关系更为密切。为了使 IOCCC 条目发挥作用,有必要将年轻的罗斯福表示为“fdr”,正如他的俗称。
这样就只剩下(integer)%4796%275%riguing
, or (integer)
%4796%275%4,自riguing
(aka argc
) 是 4。这是一个简单的哈希函数,我想它是通过使用总统姓氏及其隶属关系列表进行反复试验发现的。