Skip to content

Instantly share code, notes, and snippets.

@tokuhirom
Created July 30, 2026 02:15
Show Gist options
  • Select an option

  • Save tokuhirom/3ec0bd4bd4e15543d8523306c7681289 to your computer and use it in GitHub Desktop.

Select an option

Save tokuhirom/3ec0bd4bd4e15543d8523306c7681289 to your computer and use it in GitHub Desktop.
symbolize.raku - 任意の Raku コードを「記号だけ」のプログラムに変換する
#!/usr/bin/env raku
# symbolize.raku - 任意の Raku コードを「記号だけ」のプログラムに変換する
#
# 使い方:
# raku symbolize.raku 'say "hello"' # 引数で payload を渡す
# echo 'say 6 * 7' | raku symbolize.raku # stdin で渡す
#
# 仕組み:
# - 記号3つの XOR (A ~^ B ~^ C) で任意バイト列(= payload と "EVAL")を構築
# - payload を $_ に入れ、間接メソッド呼び出し $_."{...}"() で .EVAL を起動
# - .EVAL(メソッド形式)は MONKEY-SEE-NO-EVAL pragma を必要としない
# 生成物は英数字を1文字も含まない(単一引用符リテラルを使うため ' \ は operand から除外)
# operand に使える記号集合(' と \ は単一引用符リテラルを壊すので除外)
my @P = ((0x20..0x2F), (0x3A..0x40), (0x5B..0x60), (0x7B..0x7E)).flat
.map(*.chr).grep({ $_ ne "'" and $_ ne "\\" });
my %Pset = @P.map({ $_ => True });
# target の各文字を、記号3つの XOR で表す。3本の記号列 (A, B, C) を返す
sub triple(Str $target) {
my ($a, $b, $c) = ('', '', '');
for $target.comb -> $ch {
my $t = $ch.ord;
my ($x, $y, $z);
SEARCH: for @P -> $p1 {
for @P -> $p2 {
my $need = ($p1.ord +^ $p2.ord +^ $t).chr;
if %Pset{$need} { $x = $p1; $y = $p2; $z = $need; last SEARCH }
}
}
die "cannot encode char '$ch' (0x{$t.base(16)})" unless $x;
$a ~= $x; $b ~= $y; $c ~= $z;
}
($a, $b, $c)
}
sub MAIN(Str $payload?) {
my $code = $payload // $*IN.slurp.chomp;
die "payload が空です" unless $code.chars;
my ($a, $b, $c) = triple($code);
my ($e, $f, $g) = triple('EVAL');
my $sq = "'";
# 固定の構文部分は 「…」(リテラル引用)で。$_ や " { } を素の文字として埋める
my $prog =
「$_=」 ~ $sq ~ $a ~ $sq ~ 「~^」 ~ $sq ~ $b ~ $sq ~ 「~^」 ~ $sq ~ $c
~ $sq ~ 「;$_."{」 ~ $sq ~ $e ~ $sq ~ 「~^」 ~ $sq ~ $f ~ $sq ~ 「~^」 ~ $sq ~ $g
~ $sq ~ 「}"()」;
# 健全性チェック
my $roundtrip = ($a ~^ $b ~^ $c);
note "payload roundtrip: { $roundtrip eq $code ?? 'OK' !! 'MISMATCH' }";
note "alnum in output : { $prog ~~ /<[A..Za..z0..9]>/ ?? 'FOUND(!)' !! 'none' }";
say $prog;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment