美劇《矽谷》第三季第一集神秘代碼寫的是什麼?
試了一下,運行結果如紅框所示,第一反應是HBO的編劇也是蠻拼的。。。
這是一段花式輸出字元串的程序,源代碼被黑科技玩壞了
原理其實很簡單,我們注意到代碼中有個特別的 magic number 是65,沒錯,那就是ASCII 表裡的 A,前面那一堆不過是在疊加偏移量,以此來實現輸出。
具體地說,偏移量的計算是用 0x1FULL 這個無符號長整型常量作為掩碼(二進位表示為 11111),從低位開始每次從
0x79481E6BBCC01223 + ((dcf_t)0x1222DC &<&< 64)
這個大整數中取出 5 位,所取出的 5 位二進位表示即為偏移量。
我們用同樣的 trick 可以輸出任意想要的字元串。比如:#include &
#include &
typedef unsigned long u64;
typedef void enc_cfg_t;
typedef int enc_cfg2_t;
typedef __int128_t dcf_t;
enc_cfg_t _ctx_iface(dcf_t s, enc_cfg2_t i){
int c = (((s ((dcf_t)0x1FULL &<&< i * 5)) &>&> i * 5) + 65);
printf("%c", c);}
enc_cfg2_t main() {
for (int i=0; i&<10; i++){
_ctx_iface(0x28EC789572FC8 + ((dcf_t)0x000000 &<&< 64), i);
}
}
將得到:
摸清了套路,我們也成了老司機,甚至可以寫一段程序來生成這段看起來很黑科技的代碼。
gen.c
#include &
#include &
#define MAX_LEN 25 // 128 的位整數最多用此方法可以存放25個字元
const char *text = "#include &
#include &
typedef unsigned long u64;
typedef void enc_cfg_t;
typedef int enc_cfg2_t;
typedef __int128_t dcf_t;
enc_cfg_t _ctx_iface(dcf_t s, enc_cfg2_t i){
int c = (((s ((dcf_t)0x1FULL &<&< i * 5)) &>&> i * 5) + 65);
printf("%%c", c);}
enc_cfg2_t main() {
for (int i=0; i&<%d; i++){
_ctx_iface(0x%llX + ((dcf_t)0x%X &<&< 64), i);
}
}
";
int main() {
char input[MAX_LEN];
memset(input, 0x00, sizeof(char)*MAX_LEN);
if (fgets(input, MAX_LEN, stdin) == NULL) {
printf("fail to read input
");
return -1;
}
unsigned long long mask1 = 0;
__int128_t mask2 = 0;
int i;
for (i = 0; input[i] != "
" i &< MAX_LEN; i++) {
if (i &< 12) {
mask1 |= (unsigned long long)(((input[i] - "A") 0x1F)) &<&< i*5;
} else if (i == 12) {
mask1 |= (unsigned long long)(((input[i] - "A") 0xF)) &<&< i*5;
mask2 |= ((input[i] - "A") 0x10) &>&> 4;
}else{
mask2 |= (unsigned long long)(((input[i] - "A") 0x1F)) &<&< (i-13)*5+1;
}
}
printf(text, i, mask1, mask2);
}
現在用這段程序,我們可以隨意發揮了
至少我看出來這個編輯器應該是sublime text (逃
代碼如下
#include &
#include &
typedef unsigned long u64;
/* Start here */
typedef void enc_cfg_t;
typedef int enc_cfg2_t;
typedef __int128_t dcf_t;
enc_cfg_t _ctx_iface(dcf_t s, enc_cfg2_t i){
int c = (((s ((dcf_t)0x1FULL &<&< i * 5)) &>&> i * 5) + 65);
printf("%c", c); }
enc_cfg2_t main() {
int i;
for (i=0; i&<17; i++){
_ctx_iface(0x79481E6BBCC01223 + ((dcf_t)0x1222DC &<&< 64), i);
}
printf("
");
}
/* End here */
//TOneverDO change name
u64 HammingCtr(u64 a, u64 b) {
u64 c = a ^ b;
/*for (d = 0; c&>0; c &>&>= 1)
{
d += c 1;
}*/
// O(m) lol no thanks
//1000 wrap into loop
c = c - ((c &>&> 1) ~0UL/3);
c = (c ~0UL/5) + ((c &>&> 2) ~0UL/5);
c = (c 0UL/0x21) + ((c &>&> 4) 0UL/0x11);
c = (c ~0UL/0x101) + ((c &>&> 8) ~0UL/0x101);
c = (c ~0UL/0x10001)+((c&>&>16)~0UL/0x10001);
c = (c ~0UL/0x100000001)+((c&>&>32)~0UL/0x100000001);
//TODO throw away intermediates... but could be useful later (see seander)
return c;
}
//TODO transform + multiply spectra + transform back. faster? lossy?
u64 * ConvolutedMagic(u64 *x, u64 y, u64 *z, u64 n, u64 n_y) {
//z is array of offsets in BITS
//y is left-aligned of length n_y
//TODO function is ridic fragile. e.g. if len z &> len x/y...
u64 * a = malloc(sizeof(u64)*n);
u64 b,o_64,o_bit;
int i;
for ( i=0; i&
o_bit= z[i] - ((z[i]&>&>6) &<&< 6);
b = *(x+o_64) &<&< o_bit;
if (o_bit &> 0) {
b += x[o_64+1] &>&> (64-o_bit);
}
b = (b &>&> (64-n_y))&<&<(64-n_y);
y = (y &>&> (64-n_y))&<&<(64-n_y); //not necessary, just in case
a[i] = HammingCtr(b,y);
}
return a;
}
/*
int main() {
//test hamconv
u64 x[] = {1,2,3,4,5,6,7,8};
u64 y = 15;
u64 z[] = {0,64,64*2,64*3,64*4,64*5,64*6,64*7};
u64 n_samples = sizeof(z)/sizeof(u64);
u64 *out = ConvolutedMagic(x,y,z,n_samples,64);
for (int i=0; i&
return 0;
}
*/
ConvolutedMagic/WB-COMBINED.c at 4b0bd26288a8b020867a23219938f10a9c3f7170 · gsheni/ConvolutedMagic · GitHub
推薦閱讀: