const char * sourceCode =
"I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUg"
"PHN0cmluZy5oPgoKLyoKICAgVGhpcyBwcm9ncmFtIGlzIGEgcXVpbmUuIFRoYXQg"
"bWVhbnMsIGl0IG91dHB1dHMgaXRzIG93biBzb3VyY2Ugd2hlbiBydW4uCiAgIFRo"
"ZSBnbG9iYWwgdmFyaWFibGUgc291cmNlQ29kZSBzaW1wbHkgY29udGFpbnMgYSBi"
"YXNlNjQgZW5jb2Rpbmcgb2YKICAgZXZlcnl0aGluZyB0aGF0IGZvbGxvd3MgLS0g"
"dGhlIGNvZGUgb25seSBoYXMgdG8gcHJpbnQgaXQgYXMgZGF0YSwgYW5kIHRoZW4K"
"ICAgYXMgY29kZS4gSWRlYSB0YWtlbiBmcm9tIGh0dHA6Ly93d3cubWFkb3JlLm9y"
"Zy9+ZGF2aWQvY29tcHV0ZXJzL3F1aW5lLmh0bWwKICAgKG5vdCBzdG9sZW4sIGJ1"
"dCB0aGUgc2FtZSBwcmluY2lwbGUgaXMgYXBwbGllZCkuCiAgIFRoaXMgc2hvdWxk"
"IGNvbXBpbGUgdW5kZXIgYW55IEM5OS1jb21wbGlhbnQgY29tcGlsZXIsIGFuZCBp"
"dCdzIG5vdCBsaW1pdGVkCiAgIHRvIGFueSBzcGVjaWZpYyBhcmNoaXRlY3R1cmUu"
"CiAgIFRoZSBiYXNlNjQgZW5jb2RpbmcgdXNlcyArIGFuZCAvIGFzIDYyIGFuZCA2"
"MywgYW5kIG9taXRzIHRyYWlsaW5nIGVxdWFscy4KICAgCiAgIElmIHlvdSByZWFk"
"IHRoaXMgeW91J3JlIGEgbm9vYi4KKi8KCnZvaWQgb3V0cHV0RGF0YShjb25zdCBj"
"aGFyICopOwpjaGFyICogYmFzZTY0X2RlY29kZShjb25zdCBjaGFyICopOwp1bnNp"
"Z25lZCBjaGFyIGJhc2U2NF9pbmRleChjaGFyKTsKCmlubGluZSB2b2lkIG91dHB1"
"dCAoY29uc3QgY2hhciAqIHN0cmluZykgewogIC8vIGxldCdzIHNwYXJlIG1lIHNv"
"bWUgdHlwaW5nCiAgcHJpbnRmKCIlcyIsIHN0cmluZyk7Cn0KCmludCBtYWluICh2"
"b2lkKSB7CiAgb3V0cHV0KCJjb25zdCBjaGFyICogc291cmNlQ29kZSA9XG4iKTsg"
"Ly8gZmlyc3Qgb2YgYWxsLCB0aGUgZGVjbGFyYXRpb24uLi4KICBvdXRwdXREYXRh"
"KHNvdXJjZUNvZGUpOyAvLyAuLi5hbmQgdGhlbiB0aGUgZGF0YSBpdCBjb250YWlu"
"cwogIGNoYXIgKiBwYXJzZWRDb2RlID0gYmFzZTY0X2RlY29kZShzb3VyY2VDb2Rl"
"KTsgLy8gZGVjb2RlIHRoZSBkYXRhCiAgb3V0cHV0KHBhcnNlZENvZGUpOyAgLy8g"
"YW5kIG91dHB1dCB0aGUgY29kZSAoaW4gdGhlIGRlY29kZWQgZGF0YSkKICBmcmVl"
"KHBhcnNlZENvZGUpOyAvLyByZWxlYXNlIHRoZSBidWZmZXIgdGhhdCBiYXNlNjRf"
"ZGVjb2RlKCkgYWNxdWlyZWQKICByZXR1cm4gMDsKfQoKdm9pZCBvdXRwdXREYXRh"
"IChjb25zdCBjaGFyICogc3RyaW5nKSB7CiAgLy8gNjQgY2hhcmFjdGVycyBwZXIg"
"bGluZSwgb3RoZXIgdGhhbiB0aGUgbGFzdCBsaW5lCiAgLy8gbGFzdCBsaW5lIGhh"
"cyB0aGUgc2VtaWNvbG9uCiAgY2hhciBidWZmZXJbNjVdOwogIGJ1ZmZlcls2NF0g"
"PSAwOyAvLyBtYWtlIHN1cmUgdGhlIG51bGwgdGVybWluYXRvciBpcyBhbHJlYWR5"
"IHRoZXJlCiAgY29uc3QgY2hhciAqIGN1cnJlbnQ7CiAgdW5zaWduZWQgcmVtYWlu"
"ZGVyID0gc3RybGVuKHN0cmluZyk7CiAgZm9yIChjdXJyZW50ID0gc3RyaW5nOyBy"
"ZW1haW5kZXIgPj0gNjQ7IGN1cnJlbnQgKz0gNjQsIHJlbWFpbmRlciAtPSA2NCkg"
"ewogICAgLy8gaXRlcmF0ZSBmb3IgZXZlcnkgNjQgY2hhcmFjdGVycyBvZiB0aGUg"
"c3RyaW5nLCB1bnRpbCBub3QgZW5vdWdoIHJlbWFpbgogICAgb3V0cHV0KCIgIFwi"
"Iik7IC8vIGV2ZXJ5IGxpbmUgc3RhcnRzIGxpa2UgdGhpcwogICAgbWVtY3B5KGJ1"
"ZmZlciwgY3VycmVudCwgNjQpOyAvLyB0aGUgY3VycmVudCA2NCBjaGFyYWN0ZXJz"
"CiAgICBvdXRwdXQoYnVmZmVyKTsKICAgIG91dHB1dCgiXCJcbiIpOyAvLyBhbmQg"
"ZXZlcnkgbGluZSBlbmRzIGxpa2UgdGhpcwogIH0KICBvdXRwdXQoIiAgXCIiKTsg"
"Ly8gdGhlIGZpbmFsIGxpbmUgb2YgdGhlIGRhdGEgZGVjbGFyYXRpb24KICBtZW1j"
"cHkoYnVmZmVyLCBjdXJyZW50LCByZW1haW5kZXIpOwogIGJ1ZmZlcltyZW1haW5k"
"ZXJdID0gMDsgLy8gbWFrZSBzdXJlIHRoZSB0ZXJtaW5hdG9yIGlzIGluIHRoZSBy"
"aWdodCBwbGFjZSEKICBvdXRwdXQoYnVmZmVyKTsKICBvdXRwdXQoIlwiO1xuXG4i"
"KTsgLy8gbGFzdCBsaW5lIGhhcyBhIHNlbWljb2xvbiwgYW5kIHR3byBuZXdsaW5l"
"cwp9CgpjaGFyICogYmFzZTY0X2RlY29kZSAoY29uc3QgY2hhciAqIGRhdGEpIHsK"
"ICAvLyB0aGlzIGp1c3QgZGVjb2RlcyB0aGUgYmFzZTY0IGVuY29kZWQgZGF0YSBh"
"bmQgcmV0dXJucyB0aGUgcmVzdWx0CiAgY2hhciAqIHJlc3VsdCA9IG1hbGxvYyhz"
"dHJsZW4oZGF0YSkgKyAxKTsgLy8gdGhpcyB3aWxsIGNlcnRhaW5seSBzdWZmaWNl"
"CiAgdW5zaWduZWQgcmVtYWluaW5nID0gc3RybGVuKGRhdGEpOwogIGNvbnN0IGNo"
"YXIgKiBjdXJyZW50OyAvLyBjdXJyZW50IHBvaW50ZXIgdG8gdGhlIHNvdXJjZSBi"
"dWZmZXIKICBjaGFyICogaW5zZXJ0aW9uOyAvLyBpbnNlcnRpb24gcG9pbnRlciB0"
"byB0aGUgZGVzdGluYXRpb24gYnVmZmVyCiAgdW5zaWduZWQgY2hhciBkZWNvZGlu"
"Z3NbNF07IC8vIHRlbXBvcmFyeSBidWZmZXIKICB1bnNpZ25lZCBjaGFyIGk7CiAg"
"Zm9yIChjdXJyZW50ID0gZGF0YSwgaW5zZXJ0aW9uID0gcmVzdWx0OyAvLyBpbml0"
"aWFsIHZhbHVlcwogICAgICAgcmVtYWluaW5nID49IDQ7IC8vIGl0ZXJhdGUgd2hp"
"bGUgdGhlcmUncyBhdCBsZWFzdCA0IGJ5dGVzIHRvIGRlY29kZQogICAgICAgY3Vy"
"cmVudCArPSA0LCBpbnNlcnRpb24gKz0gMywgcmVtYWluaW5nIC09IDQpIHsgLy8g"
"aW5jcmVtZW50IGFuZCBzdWNoCiAgICBmb3IgKGkgPSAwOyBpIDwgNDsgaSArKykg"
"ZGVjb2RpbmdzW2ldID0gYmFzZTY0X2luZGV4KGN1cnJlbnRbaV0pOwogICAgLy8g"
"YW5kIG5vdyBkZWNvZGUgdGhlIGJhc2U2NCBkYXRhLiBUaGlzIGNvZGUgaXMgYXdm"
"dWwsIEkga25vdwogICAgaW5zZXJ0aW9uWzBdID0gKGRlY29kaW5nc1swXSA8PCAy"
"KSB8IChkZWNvZGluZ3NbMV0gPj4gNCk7CiAgICBpbnNlcnRpb25bMV0gPSAoKGRl"
"Y29kaW5nc1sxXSAmIDE1KSA8PCA0KSB8IChkZWNvZGluZ3NbMl0gPj4gMik7CiAg"
"ICBpbnNlcnRpb25bMl0gPSAoKGRlY29kaW5nc1syXSAmIDMpIDw8IDYpIHwgZGVj"
"b2RpbmdzWzNdOwogIH0KICBpZiAocmVtYWluaW5nKSAvLyBpZiBzb21ldGhpbmcg"
"cmVtYWlucywgZGVjb2RlIGl0IHRvbwogICAgZm9yIChpID0gMDsgaSA8IHJlbWFp"
"bmluZzsgaSArKykgZGVjb2RpbmdzW2ldID0gYmFzZTY0X2luZGV4KGN1cnJlbnRb"
"aV0pOwogIHN3aXRjaCAocmVtYWluaW5nKSB7CiAgICBjYXNlIDM6CiAgICAgIGlu"
"c2VydGlvblsxXSA9ICgoZGVjb2RpbmdzWzFdICYgMTUpIDw8IDQpIHwgKGRlY29k"
"aW5nc1syXSA+PiAyKTsKICAgICAgLy8gbm8gYnJlYWsgb24gcHVycG9zZSEKICAg"
"IGNhc2UgMjoKICAgICAgaW5zZXJ0aW9uWzBdID0gKGRlY29kaW5nc1swXSA8PCAy"
"KSB8IChkZWNvZGluZ3NbMV0gPj4gNCk7CiAgfQogIGluc2VydGlvbiArPSByZW1h"
"aW5pbmcgPyByZW1haW5pbmcgOiAxOyAvLyB1Z2x5LCBidXQgd29ya3MKICBpbnNl"
"cnRpb25bLTFdID0gMDsgLy8gYmVmb3JlIHRoZSB3dGYsIHRoaXMganVzdCBhZGRz"
"IGEgbnVsbCB0ZXJtaW5hdG9yCiAgcmV0dXJuIHJlYWxsb2MocmVzdWx0LCBpbnNl"
"cnRpb24gLSByZXN1bHQpOyAvLyBva2F5LCB5b3UgY2FuIHd0ZiBub3cKfQoKdW5z"
"aWduZWQgY2hhciBiYXNlNjRfaW5kZXggKGNoYXIgY2hhcmFjdGVyKSB7CiAgLy8g"
"dGhpcyBmdW5jdGlvbiByZXR1cm5zIGEgbnVtYmVyIGZyb20gMCB0byA2MyBpbmRp"
"Y2F0aW5nIHdoYXQgdGhlIHZhbHVlCiAgLy8gb2YgYSBjZXJ0YWluIGJhc2U2NCBl"
"bmNvZGluZyBjaGFyYWN0ZXIgaXMKICAvLyBBLVo6IDAtMjUsIGEtejogMjYtNTEs"
"IDAtOTogNTItNjEsICs6IDYyLCAvOiA2MwogIGlmIChjaGFyYWN0ZXIgPT0gJysn"
"KSByZXR1cm4gNjI7CiAgaWYgKGNoYXJhY3RlciA9PSAnLycpIHJldHVybiA2MzsK"
"ICBpZiAoKGNoYXJhY3RlciA+PSAnMCcpICYmIChjaGFyYWN0ZXIgPD0gJzknKSkg"
"cmV0dXJuIGNoYXJhY3RlciArIDUyIC0gJzAnOwogIGlmICgoY2hhcmFjdGVyID49"
"ICdBJykgJiYgKGNoYXJhY3RlciA8PSAnWicpKSByZXR1cm4gY2hhcmFjdGVyIC0g"
"J0EnOwogIGlmICgoY2hhcmFjdGVyID49ICdhJykgJiYgKGNoYXJhY3RlciA8PSAn"
"eicpKSByZXR1cm4gY2hhcmFjdGVyICsgMjYgLSAnYSc7CiAgcmV0dXJuIDI1NTsg"
"Ly8gaW52YWxpZCB2YWx1ZQp9Cg";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
This program is a quine. That means, it outputs its own source when run.
The global variable sourceCode simply contains a base64 encoding of
everything that follows -- the code only has to print it as data, and then
as code. Idea taken from http://www.madore.org/~david/computers/quine.html
(not stolen, but the same principle is applied).
This should compile under any C99-compliant compiler, and it's not limited
to any specific architecture.
The base64 encoding uses + and / as 62 and 63, and omits trailing equals.
If you read this you're a noob.
*/
void outputData(const char *);
char * base64_decode(const char *);
unsigned char base64_index(char);
inline void output (const char * string) {
// let's spare me some typing
printf("%s", string);
}
int main (void) {
output("const char * sourceCode =\n"); // first of all, the declaration...
outputData(sourceCode); // ...and then the data it contains
char * parsedCode = base64_decode(sourceCode); // decode the data
output(parsedCode); // and output the code (in the decoded data)
free(parsedCode); // release the buffer that base64_decode() acquired
return 0;
}
void outputData (const char * string) {
// 64 characters per line, other than the last line
// last line has the semicolon
char buffer[65];
buffer[64] = 0; // make sure the null terminator is already there
const char * current;
unsigned remainder = strlen(string);
for (current = string; remainder >= 64; current += 64, remainder -= 64) {
// iterate for every 64 characters of the string, until not enough remain
output(" \""); // every line starts like this
memcpy(buffer, current, 64); // the current 64 characters
output(buffer);
output("\"\n"); // and every line ends like this
}
output(" \""); // the final line of the data declaration
memcpy(buffer, current, remainder);
buffer[remainder] = 0; // make sure the terminator is in the right place!
output(buffer);
output("\";\n\n"); // last line has a semicolon, and two newlines
}
char * base64_decode (const char * data) {
// this just decodes the base64 encoded data and returns the result
char * result = malloc(strlen(data) + 1); // this will certainly suffice
unsigned remaining = strlen(data);
const char * current; // current pointer to the source buffer
char * insertion; // insertion pointer to the destination buffer
unsigned char decodings[4]; // temporary buffer
unsigned char i;
for (current = data, insertion = result; // initial values
remaining >= 4; // iterate while there's at least 4 bytes to decode
current += 4, insertion += 3, remaining -= 4) { // increment and such
for (i = 0; i < 4; i ++) decodings[i] = base64_index(current[i]);
// and now decode the base64 data. This code is awful, I know
insertion[0] = (decodings[0] << 2) | (decodings[1] >> 4);
insertion[1] = ((decodings[1] & 15) << 4) | (decodings[2] >> 2);
insertion[2] = ((decodings[2] & 3) << 6) | decodings[3];
}
if (remaining) // if something remains, decode it too
for (i = 0; i < remaining; i ++) decodings[i] = base64_index(current[i]);
switch (remaining) {
case 3:
insertion[1] = ((decodings[1] & 15) << 4) | (decodings[2] >> 2);
// no break on purpose!
case 2:
insertion[0] = (decodings[0] << 2) | (decodings[1] >> 4);
}
insertion += remaining ? remaining : 1; // ugly, but works
insertion[-1] = 0; // before the wtf, this just adds a null terminator
return realloc(result, insertion - result); // okay, you can wtf now
}
unsigned char base64_index (char character) {
// this function returns a number from 0 to 63 indicating what the value
// of a certain base64 encoding character is
// A-Z: 0-25, a-z: 26-51, 0-9: 52-61, +: 62, /: 63
if (character == '+') return 62;
if (character == '/') return 63;
if ((character >= '0') && (character <= '9')) return character + 52 - '0';
if ((character >= 'A') && (character <= 'Z')) return character - 'A';
if ((character >= 'a') && (character <= 'z')) return character + 26 - 'a';
return 255; // invalid value
}
Comments