4
\$\begingroup\$

Your challenge is to output a Base64-encoded version of your source code, and optionally a line break. You must output the correct padding, if any. Standard quine rules apply, shortest answer wins.

It must be a valid RFC 4648 encoded base64 string, with no linebreaks (except optionally a trailing newline).

Test cases:

h -> aA==
PPCG! -> UFBDRyE=
Programming Puzzles and Code Golf -> UHJvZ3JhbW1pbmcgUHV6emxlcyBhbmQgQ29kZSBHb2xm

Base64 table

0   A   16  Q   32  g   48  w
1   B   17  R   33  h   49  x
2   C   18  S   34  i   50  y
3   D   19  T   35  j   51  z
4   E   20  U   36  k   52  0
5   F   21  V   37  l   53  1
6   G   22  W   38  m   54  2
7   H   23  X   39  n   55  3
8   I   24  Y   40  o   56  4
9   J   25  Z   41  p   57  5
10  K   26  a   42  q   58  6
11  L   27  b   43  r   59  7
12  M   28  c   44  s   60  8
13  N   29  d   45  t   61  9
14  O   30  e   46  u   62  +
15  P   31  f   47  v   63  /

If you want to test your submission, try base64encode.org.

\$\endgroup\$
11
\$\begingroup\$

Bash, 27 bytes

trap -- 'trap|base64' EXIT

Based on this Bash quine. Note the trailing linefeed.

Try it online!

\$\endgroup\$
  • \$\begingroup\$ why do I obtain dHJhcCAtLSAndHJhcHxiYXNlNjQnIEVYSVQ= and dHJhcCAtLSAndHJhcHxiYXNlNjQnIEVYSVQK ? (last char diff) \$\endgroup\$ – V. Courtois Jul 17 '17 at 12:41
  • \$\begingroup\$ The program needs a trailing linefeed to be a valid base64 quine, which got removed by the syntax highlighter. \$\endgroup\$ – Dennis Jul 17 '17 at 14:22
  • \$\begingroup\$ I see ! Thanks. \$\endgroup\$ – V. Courtois Jul 17 '17 at 14:25
6
\$\begingroup\$

Javascript (ES6), 17 bytes

f=_=>btoa(`f=`+f)

I thought this solution would be obvious...

f=_=>btoa(`f=`+f)
console.log(f())
console.log(atob(f()))

\$\endgroup\$
4
\$\begingroup\$

Python, 133 112 bytes

from base64 import*;s=b'from base64 import*;s=%r;print(b64encode(s%%s).decode())';print(b64encode(s%s).decode())

Base64 representation:

ZnJvbSBiYXNlNjQgaW1wb3J0KjtzPWInZnJvbSBiYXNlNjQgaW1wb3J0KjtzPSVyO3ByaW50KGI2NGVuY29kZShzJSVzKS5kZWNvZGUoKSknO3ByaW50KGI2NGVuY29kZShzJXMpLmRlY29kZSgpKQ==

Try it online!

\$\endgroup\$
3
\$\begingroup\$

C (gcc), 342 bytes

f(a){putchar(a>61?43+a%2*4:a>51?a-4:a+65+a/26*6);}main(a){char*s="f(a){putchar(a>61?43+a%2*4:a>51?a-4:a+65+a/26*6);}main(a){char*s=%c%s%c,*t=malloc(342);for(sprintf(t,s,34,s,34);*t;f(*t%4*16+*++t/16),f(*t%16*4+*++t/64),f(*t++%64))f(*t/4);}",*t=malloc(342);for(sprintf(t,s,34,s,34);*t;f(*t%4*16+*++t/16),f(*t%16*4+*++t/64),f(*t++%64))f(*t/4);}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Mathematica, 108 bytes

Print[StringDelete[ExportString[StringJoin["Print[", ToString[#0, InputForm], "[]]"], "Base64"], "\n"] & []]

Full program. The spaces are necessary as part of the InputForm formatting. Output, note the trailing linefeed character:

UHJpbnRbU3RyaW5nRGVsZXRlW0V4cG9ydFN0cmluZ1tTdHJpbmdKb2luWyJQcmludFsiLCBUb1N0cmluZ1sjMCwgSW5wdXRGb3JtXSwgIltdXSJdLCAiQmFzZTY0Il0sICJcbiJdICYgW11d

\$\endgroup\$
2
\$\begingroup\$

Alice, 72 69 bytes

-3 bytes thanks to Martin Ender.

".w6+55*&w.q+!]k;9&wq4-!]kq&[d.t&w;q,ww].4%~4:k;28d3:&wq&[&]?ow4*+k@;

Base 64 representation:

Ii53Nis1NSomdy5xKyFdazs5JndxNC0hXWtxJltkLnQmdztxLHd3XS40JX40Oms7MjhkMzomd3EmWyZdP293NCora0A7

If anything, the base 64 representation looks less inscrutable than the original program.

Try it online!

Explanation

Since Alice has no base64 built-in, the vast majority of this program is a reduced implementation of base64. The quine framework prevents me from using ' to define constants in two bytes, but it also has some advantages. As luck would have it, the length of the source code is divisible by 3, and the characters >, ?, and ~ do not appear at the end of a 3-character block.

The first step is to create (most of) the base64 alphabet. The characters + and / do not appear in the base64 representation of the source code, so we do not need to handle them. This saves 9 bytes.

"      wrap the entire source code in a string and push each byte

.      copy ; from top of stack (i.e., push 59)
w      push return address (i.e., do the following twice)
6+     add 6 to the constant on the stack 
       this gives us 65 in the first iteration, and 71 in the second
55*w   do the following 26 times:
.q+    add tape position to constant
!      store at tape position
]      move tape right
k      return to pushed return address (end both loops)
;      remove constant from the stack, since it's no longer needed
9&w    do 10 times:
q4-    tape position minus 4
!      store at tape position
]      move tape right
k      repeat
q&[    return to position 0

Positions 0-61 on the tape are now filled with their base64 character equivalents. We now convert the source code to base 4.

d.     push stack depth (length of code excluding "), and put a useless copy below it
t&w    do that many times:
;      remove top of stack (copy of length on first iteration, 0 otherwise)
q,     move next byte to top of stack (using tape position as a register)
ww     do 4 times:
]      move tape forward (increase counter)
.      duplicate current byte or part thereof
4%     mod 4
~      swap: work with other copy
4:     divide by 4
k      repeat (end both loops)
;28    remove the excess 0 and push the base 4 representation of ",
       except that the first three base 4 digits are already in base 64

Finally, we convert from base 4 to base64 and output.

d3:&w  push return address once for each output character
q&[    move tape to position 0
&]     move tape to position corresponding to base 64 digit
?      get character from tape
o      output
w4*+   convert next base 64 digit (equivalent to 4*+4*+)
k      repeat until stack is empty
@      terminate
\$\endgroup\$
  • \$\begingroup\$ If you can save another byte elsewhere, could you shorten 6a*t by putting a ; at the end of the program and a . after the "? \$\endgroup\$ – Martin Ender Feb 26 '18 at 10:27
  • \$\begingroup\$ As it turns out, rearranging my base 4 -> base 64 conversion allowed me to save a third byte. \$\endgroup\$ – Nitrodon Feb 27 '18 at 1:16
1
\$\begingroup\$

Java 8, 202 bytes

v->{String s="v->{String s=%c%s%1$c;return java.util.Base64.getEncoder().encodeToString(s.format(s,34,s).getBytes());}";return java.util.Base64.getEncoder().encodeToString(s.format(s,34,s).getBytes());}

Explanation:

Try it online.

  • The String s contains the unformatted source code.
  • %s is used to input this String into itself with the s.format(...).
  • %c, %1$c and the 34 are used to format the double-quotes.
  • s.format(s,34,s) puts it all together.

And then java.util.Base64.getEncoder().encodeToString(....getBytes()) is used to encode the entire source code to a Base64-String.

Try it here with the Base64-encoding part removed to prove it's a quine.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.