Last active
January 18, 2019 13:22
-
-
Save xsot/cd08dfb284474c12aedec7497060e602 to your computer and use it in GitHub Desktop.
Minimal charset quine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
names = { | |
43 => 'e', | |
'prog' => 'x', # the program will be stored in this variable | |
'template' => 'c', | |
0 => 'ee', # register? | |
1 => 'ex', | |
2 => 'ec', | |
4 => 'xe', | |
8 => 'xx', | |
16 => 'xc', | |
32 => 'ce', | |
64 => 'cc', | |
'data' => 'cx', # source program will be encoded here | |
} | |
# string to be executed during last exec step | |
# this needs to be constructed by the encoder | |
execstring = 'h,t=cx.split(";;");print h+\'"""\'+cx+\'""";\'+t' | |
charset = ('exc="%;'+execstring).chars.uniq.sort | |
codepoints = charset.map(&:ord) | |
init = ( | |
# create template for joining multiple characters | |
"#{names['template']}=\"%c%%c%%%%c%%%%%%%%c\";" + | |
# create 1 | |
"#{names[1]}=#{names['template']}==#{names['template']};" + | |
# create 0 | |
"#{names[0]}=#{names['template']}==\"\";" + | |
# create 3 | |
# store it at names[43] temporarily | |
"exec\"#{names[43]}=%x%%x\"%#{names[1]}%#{names[1]};" + | |
"exec\"#{names[43]}%%%%%%%%=%x%%x%%%%x\"%#{names[0]}%#{names[1]}%#{names[0]};" + | |
# create 4 | |
# this step overwrites the value stored at names[0] | |
"exec\"#{names[0]}=%x%%x\"%#{names[43]}%#{names[0]};" + | |
"exec\"#{names[0]}%%%%=%x%%x\"%#{names[1]}%#{names[43]};" + | |
# create 43 | |
"exec\"#{names[43]}=%x%%x\"%#{names[0]}%#{names[43]};" | |
) | |
# create powers of 2 | |
(1..6).map{ |i| 2**i }.each do |i| | |
init += "exec\"#{names[i]}=#{names[i/2]}%c#{names[i/2]}\"%#{names[43]};" | |
end | |
codepoints.map.with_index do |c, i| | |
# skip code point if it is already aliased (e.g. power of two) | |
next if names.include?(c) | |
def genname(length, i) | |
varname = '' | |
length.times do | |
varname += 'exc'[i%3] | |
i /= 3 | |
end | |
return varname | |
end | |
# generate a new name for this variable | |
if i < 27 | |
names[c] = genname(3, i) | |
else | |
i -= 27 | |
names[c] = genname(4, i) | |
end | |
# decompose code point into powers of two | |
rem = c | |
pows = [] | |
while rem > 0 | |
pows << (rem&-rem) | |
rem -= rem&-rem | |
end | |
# generate the code that defines this variable | |
front = "exec\"#{names[c]}=#{names[pows.pop]}" | |
back = '"' | |
pows.map.with_index do |p, i| | |
front += '%'*(2**i) + 'c' + names[p] | |
back += '%' + names[43] | |
end | |
init += front + back + ';' | |
end | |
# length of execstring must be a multiple of 4 | |
length = execstring.size | |
if length%4 != 0 | |
puts length%4 | |
exit | |
end | |
# generate code to build execstring | |
builder = "" | |
i = 0 | |
while i < length | |
# extract the next four characters | |
w, x, y, z = (0..3).map{|j| names[execstring[i+j].ord]} | |
if builder == "" | |
builder += "exec\"#{names['prog']}=#{names['template']}%#{w}%#{x}%#{y}%#{z}\";" | |
else | |
builder += "exec\"#{names['prog']}%c=#{names['template']}%%#{w}%%#{x}%%#{y}%%#{z}\"%#{names[43]};" | |
end | |
i += 4 | |
end | |
header = init+builder | |
# to be appended to actual program | |
# exec'exec%c___'%___ | |
execstep = "exec\"exec%c#{names['prog']}\"%#{names[32]}" | |
datastring="#{names['data']}=\"\"\"#{header}#{names['data']}=;;#{execstep}\"\"\";" | |
puts header+datastring+execstep |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
c="%c%%c%%%%c%%%%%%%%c";ex=c==c;ee=c=="";exec"e=%x%%x"%ex%ex;exec"e%%%%%%%%=%x%%x%%%%x"%ee%ex%ee;exec"ee=%x%%x"%e%ee;exec"ee%%%%=%x%%x"%ex%e;exec"e=%x%%x"%ee%e;exec"ec=ex%cex"%e;exec"xe=ec%cec"%e;exec"xx=xe%cxe"%e;exec"xc=xx%cxx"%e;exec"ce=xc%cxc"%e;exec"cc=ce%cce"%e;exec"xee=ce%cec"%e;exec"cee=ce%cex%%cxe"%e%e;exec"exe=ce%cex%%cec%%%%cxe"%e%e%e;exec"xxe=ce%cxx"%e;exec"cxe=ce%cex%%cxx"%e%e;exec"xce=ce%cxe%%cxx"%e%e;exec"cce=ce%cec%%cxe%%%%cxx"%e%e%e;exec"eex=ce%cex%%cec%%%%cxx%%%%%%%%cxc"%e%e%e%e;exec"xex=ce%cex%%cxe%%%%cxx%%%%%%%%cxc"%e%e%e%e;exec"cex=cc%cex%%cec%%%%cce"%e%e%e;exec"exx=cc%cex%%cxe%%%%cce"%e%e%e;exec"xxx=cc%cxx%%cce"%e%e;exec"cxx=cc%cex%%cxx%%%%cce"%e%e%e;exec"ecx=cc%cxe%%cxx%%%%cce"%e%e%e;exec"xcx=cc%cec%%cxe%%%%cxx%%%%%%%%cce"%e%e%e%e;exec"ccx=cc%cxc%%cce"%e%e;exec"eec=cc%cec%%cxc%%%%cce"%e%e%e;exec"xec=cc%cex%%cec%%%%cxc%%%%%%%%cce"%e%e%e%e;exec"cec=cc%cxe%%cxc%%%%cce"%e%e%e;exec"exc=cc%cxx%%cxc%%%%cce"%e%e%e;exec"x=c%xxx%xce%cec%xex";exec"x%c=c%%cex%%exc%%cce%%xec"%e;exec"x%c=c%%ccx%%ecx%%cxx%%cec"%e;exec"x%c=c%%xxe%%xee%%eex%%eex"%e;exec"x%c=c%%xee%%cxe%%eex%%ccx"%e;exec"x%c=c%%eec%%cxx%%xcx%%cec"%e;exec"x%c=c%%ce%%xxx%%e%%exe"%e;exec"x%c=c%%xee%%xee%%xee%%exe"%e;exec"x%c=c%%e%%cex%%exc%%e"%e;exec"x%c=c%%exe%%xee%%xee%%xee"%e;exec"x%c=c%%eex%%exe%%e%%cec"%e;cx="""c="%c%%c%%%%c%%%%%%%%c";ex=c==c;ee=c=="";exec"e=%x%%x"%ex%ex;exec"e%%%%%%%%=%x%%x%%%%x"%ee%ex%ee;exec"ee=%x%%x"%e%ee;exec"ee%%%%=%x%%x"%ex%e;exec"e=%x%%x"%ee%e;exec"ec=ex%cex"%e;exec"xe=ec%cec"%e;exec"xx=xe%cxe"%e;exec"xc=xx%cxx"%e;exec"ce=xc%cxc"%e;exec"cc=ce%cce"%e;exec"xee=ce%cec"%e;exec"cee=ce%cex%%cxe"%e%e;exec"exe=ce%cex%%cec%%%%cxe"%e%e%e;exec"xxe=ce%cxx"%e;exec"cxe=ce%cex%%cxx"%e%e;exec"xce=ce%cxe%%cxx"%e%e;exec"cce=ce%cec%%cxe%%%%cxx"%e%e%e;exec"eex=ce%cex%%cec%%%%cxx%%%%%%%%cxc"%e%e%e%e;exec"xex=ce%cex%%cxe%%%%cxx%%%%%%%%cxc"%e%e%e%e;exec"cex=cc%cex%%cec%%%%cce"%e%e%e;exec"exx=cc%cex%%cxe%%%%cce"%e%e%e;exec"xxx=cc%cxx%%cce"%e%e;exec"cxx=cc%cex%%cxx%%%%cce"%e%e%e;exec"ecx=cc%cxe%%cxx%%%%cce"%e%e%e;exec"xcx=cc%cec%%cxe%%%%cxx%%%%%%%%cce"%e%e%e%e;exec"ccx=cc%cxc%%cce"%e%e;exec"eec=cc%cec%%cxc%%%%cce"%e%e%e;exec"xec=cc%cex%%cec%%%%cxc%%%%%%%%cce"%e%e%e%e;exec"cec=cc%cxe%%cxc%%%%cce"%e%e%e;exec"exc=cc%cxx%%cxc%%%%cce"%e%e%e;exec"x=c%xxx%xce%cec%xex";exec"x%c=c%%cex%%exc%%cce%%xec"%e;exec"x%c=c%%ccx%%ecx%%cxx%%cec"%e;exec"x%c=c%%xxe%%xee%%eex%%eex"%e;exec"x%c=c%%xee%%cxe%%eex%%ccx"%e;exec"x%c=c%%eec%%cxx%%xcx%%cec"%e;exec"x%c=c%%ce%%xxx%%e%%exe"%e;exec"x%c=c%%xee%%xee%%xee%%exe"%e;exec"x%c=c%%e%%cex%%exc%%e"%e;exec"x%c=c%%exe%%xee%%xee%%xee"%e;exec"x%c=c%%eex%%exe%%e%%cec"%e;cx=;;exec"exec%cx"%ce""";exec"exec%cx"%ce |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment