混源

初见端倪

同一个符号在不同的编程语言中意义不同。比如 ; 在 C 语言家族中是语句的结束符,在 Lisp 语言家族中是注释符号。

这也就是一种语言的代码通常在另一种语言编译失败的原因。

利用这一点,可以实现多语言混写。即一段能通过多语言编译的代码。

比如

1
2
3
4
5
6
7
# define x u /*      v 
# :::::::::::::::::::>>>>>>>$$$a"muroftih"#[>:#,_@]
eval 'echo "hitforum";exit';sub echo { print "@_\n"}
__END__>++++++++++>++++++++++[>+++++++++++>++++++++++
+<<-]>------.+.>++++++.<---.+++++++++.>--.+++
.<--.<<. */
main() { printf ("hitforum\n"); }

这段代码可以在 C 、Shell 、Perl 、BrainFuck 、Befunge 、Whitespace 6 个语言环境下运行。

在 C 语言相当于

1
2
3
4
5
6
7
# define x u /*      v 
# :::::::::::::::::::>>>>>>>$$$a"muroftih"#[>:#,_@]
eval 'echo "hitforum";exit';sub echo { print "@_\n"}
__END__>++++++++++>++++++++++[>+++++++++++>++++++++++
+<<-]>------.+.>++++++.<---.+++++++++.>--.+++
.<--.<<. */
main() { printf ("hitforum\n"); }

因为 /**/ 是 C 语言的注释符号。

所以在 C 下代码相当于

1
2
# define x u
main() { printf ("hitforum\n"); }

在 Shell 下

1
2
3
4
5
6
7
# define x u /*      v 
# :::::::::::::::::::>>>>>>>$$$a"muroftih"#[>:#,_@]
eval 'echo "hitforum";exit';sub echo { print "@_\n"}
__END__>++++++++++>++++++++++[>+++++++++++>++++++++++
+<<-]>------.+.>++++++.<---.+++++++++.>--.+++
.<--.<<. */
main() { printf ("hitforum\n"); }

# 是 Shell 的注释符号,所以后面的内容视为注释忽略了。

exit 退出 Shell 。所以后面的内容没有意义了。

所以在 Shell 下代码相当于

1
eval 'echo "hitforum";exit'

在 BrainFuck 下

1
2
3
4
5
6
7
# define x u /*      v 
# :::::::::::::::::::>>>>>>>$$$a"muroftih"#[>:#,_@]
eval 'echo "hitforum";exit';sub echo { print "@_\n"}
__END__>++++++++++>++++++++++[>+++++++++++>++++++++++
+<<-]>------.+.>++++++.<---.+++++++++.>--.+++
.<--.<<. */
main() { printf ("hitforum\n"); }

因为 BrainFuck 的原语只有 8 个符号 所以其他符号都会被忽略。

所以在 BrainFuck 下代码相当于

1
2
3
4
5
>>>>>>>[>,]

>++++++++++>++++++++++[>+++++++++++>++++++++++
+<<-]>------.+.>++++++.<---.+++++++++.>--.+++
.<--.<<.

在 Whitespace 下

1
2
3
4
5
6
7
# define x u /*      v 
# :::::::::::::::::::>>>>>>>$$$a"muroftih"#[>:#,_@]
eval 'echo "hitforum";exit';sub echo { print "@_\n"}
__END__>++++++++++>++++++++++[>+++++++++++>++++++++++
+<<-]>------.+.>++++++.<---.+++++++++.>--.+++
.<--.<<. */
main() { printf ("hitforum\n"); }

因为 Whitespace 的原语只有空格,制表符,换行 ,所以其他字符都会被忽略。

所以在 Whitespace 下相当于

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[Space][Space][Space][Space][Tab][Space][Space][LF]
[Space][Space][LF]
[Space][Space][Space][Space][Space][Space][Tab][Space][Space][LF]
[Space][Space][LF]
[Tab][Tab][Space][Space][Space][LF]
[Space][Space][LF]
[Space][Space][Space][Space][Tab][Space][Space][Space][Space][LF]
[Space][Space][LF]
[Tab][Tab][Space][Space][Space][LF]
[Space][Space][LF]
[Tab][Tab][Space][Space][Space][LF]
[Space][Space][LF]
[Tab][Tab][Space][Space][Space][LF]
[Space][Space][LF]
[Tab][Tab][Space][Space][Space][LF]
[Space][Space][LF]
[Tab][Tab][LF]
[Space][Space][LF]
[Space][Space][Space][LF]
[LF]
[LF]

百花齐放

除了 C 语言的混源,还有更多语言的混合。

比如 40 中语言的混合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    #  1"16" 3//v\(@#/;"14"\Dv
#/*`3 auaaZ<>16/"<"6/b.q@")(22)S# ␉␉␉␉
#yy␉;36!@
### ␉
#=␉>
#[#yy#yy0l0mx01k1k0l0ix0jx0h0h1d111P0eU0bx0b0o1d0b0e0e00x1d0i0fx0g0n0n11x0o0n0cx0c0o0f0c0gx0g0f0h0j0j0i0001k10mx0m0l11111100(^_)
#`<`␉|
print((eval("1\x2f2")and( 9 )or(13 ))-(0and 4)^1<<(65)>>(62))or'(\{(\{})(\{}[()])}\{}\{}\{})'#46(8+9+9+9+9+=!)#1111|=/=1/24=x=9[<$+@+-@@@@=>+<@@@=>+<?#>+.--.]/
__DATA__=1#//
#.\."12"*␉
###; console.log 39
""""#//
=begin␉//
#*/
#define␉z sizeof 'c'-1?"38":"37"
#include<stdio.h>
int main() /*/
#()`#`\'*/{puts(z);;}/*'``
$'main'␉//
#-3o4o#$$$
<>3N.<>␉//
#xx\"R++++++++++++++++++\"++++++++++++++++++.----.
#x%~~~+␉+~*ttt*.x
#xx++U++++++++++++++++v<L>4n;
=end #//
"""#"#//
#0]#echo 21#/(\[FAC,1<-#2FAC,1SUB#1<-#52FAC,1SUB#2<-#32FACLEGEREEX,1PLEASEGIVEUPPLEASE) ap
#_|#o51~nJ\
#0␛dggi2␛`␉|1|6$//''25 >>>#>27.say# =#print(17)###^_^_7LEintndus({})!<>+]/*///Z/}23!@222999"26

详情参见 Polyglot 在 Stackoverflow 上的讨论

参考链接