10
\$\begingroup\$

The robber's thread is here

The cops task is to write a function or program that, when given an input of itself, outputs a finite deterministic string. If the program is given a different input, it should return a different output.

Rules:

  • Submissions consist of
    • Language name
      • If any flags are used, they should be revealed.
    • Byte count of program
    • Byte count of output
    • Output
      • If it is particularly long, please provide a pastebin or something similar
      • If it contains unprintables, please provide a hexdump.
      • Trailing newlines and whitespace should be included in the output
    • Where the input is coming from (STDIN, command line, etc.)
  • If applicable, you may assume that the byte representing EOF is not present in the input, unless you use that byte in your program.
  • If your program is cracked, add a link to the corresponding answer in the robber's thread in your title.
  • Your program is not safe until a week has passed and you mark it so.
  • I disapprove of techniques like seeding random with the input or cryptographic hash functions. I can't stop them, but I will not be accepting a solution that utilises either of these. Also note that some of these techniques might have collisions, where a different string produces the same output.
  • Your goal is to have the shortest output. The shortest safe solution posted within three weeks of posting this question wins!

The robber's task is to find a program of size equal to or less than the original, which also obeys the above rules.

If a robber cracks your program with a different solution than intended, then you have the opportunity to 'uncrack' it by proving that the robber's solution is incorrect. You can do this by finding an input to the robber's program that will produce the same output.

Example Submission:

brainfuck, 10 bytes, Score: 10

]<.[<],>[,

This solution is ,[>,]<[.<] which simply reverses the input

Good luck!

\$\endgroup\$
  • \$\begingroup\$ "If the program is given a different input, it should return a different output." Does this means the program should never output the same thing for other inputs? Or does this means the program should not constantly output something regardless the input? (EXIST an input not equals to itself, vs., FORALL inputs not equal to itself, return a different output.) \$\endgroup\$ – tsh Nov 6 '18 at 7:58
  • \$\begingroup\$ @tsh Only the input of itself must have a unique output. For example, a valid submission could be a self-identifying program, which outputs 1 for itself and 0 otherwise \$\endgroup\$ – Jo King Nov 6 '18 at 8:18
  • \$\begingroup\$ @JoKing So your example Python 3 submission is invalid? Because it obvoiusly also outputs 1021111143210532105110321051101121171164041581121141051101164011111410040105414410111010061393941 for some other strings. \$\endgroup\$ – Lynn Nov 7 '18 at 13:00
  • \$\begingroup\$ @lynn You're right. I've removed that example \$\endgroup\$ – Jo King Nov 7 '18 at 13:30

13 Answers 13

4
\$\begingroup\$

7, 31 characters, score 30, safe but possibly broken?

A 7 program is normally just a number, but it can contain whitespace, splitting it into multiple numbers. This submission therefore consists of two numbers (which are implicitly concatenated by the 7 interpreter), and the program likewise takes two numbers as input, via standard input. (The "31 characters" in the header is the total length of the two numbers, plus one separating whitespace character; the digits that make up the numbers are interpreted as octal when used as a program, but decimal when used as an input, and it's the digits that are the same in the two cases, not the actual numbers. Note that it's irrelevant either when treated as a program, or when treated as an input, whether you separate them with a space or a newline; I hope that doesn't invalidate the submission.)

The expected output is the following number (expressed here in decimal, as that's the output format that the 7 interpreter uses):

238363505302130098723162537059

Note that the 7 interpreter linked from the Esolang wiki internally stores numbers in unary, meaning you're unlikely to have enough memory to actually run the program on itself to see what it does. I verified the program via working out its behaviour manually, and testing it on small inputs to verify that it did what I expected it to do. An alternative approach would be to write an interpreter that uses a more efficient method of storing numbers.

Avoiding cracks here was something of a pain, but I'm finally now satisfied that no two numbers other than those in the program itself are capable of producing 238363505302130098723162537059 as output. (EDIT 1 week later: I may have been wrong, depending on how you interpret the question; see below.)

Solution

The original program was:

711170237403706
111723603700633
This program takes two numbers \$x\$ and \$y\$, and calculates the result of the expression \$3xy-y-2\$ (i.e. \$y(3x-1)-2\$). If we perform this calculation at \$x=711170237403706\$ and \$y=111723603700633\$, we get a result of \$238363505302130098723162537059\$ as required.

It was intended that no other input will give the desired result because:

The input must be chosen such that \$y(3x-1)-2=238363505302130098723162537059\$, i.e. \$y(3x-1)=238363505302130098723162537061\$ (adding 2 to both sides). This number is a semiprime, with only two factors: \$111723603700633\$ and \$2133510712211117\$. Only one of these numbers, \$2133510712211117\$, can be expressed in the form \$3x-1\$ (giving \$(3 \times 711170237403706)-1=2133510712211117\$). So we can uniquely identify which number is \$x\$ and which is \$y\$, meaning that only one input works.

However, depending on how you interpret the question, there may be a second input that produces the desired output (thus invalidating this solution):

Unfortunately, there are two multiplicative partitions of a semiprime into two factors: one is to divide it into the two prime factors, but the other is the trivial partition consisting of \$1\$ and the number itself. \$1\$ cannot be written in the form \$3x-1\$ with integer \$x\$, but the desired output can be; thus a potential meta-crack involves giving the input as \$79454501767376699574387512354\$ and \$1\$. However, the first number here involves characters (\$8\$ and \$9\$) which are not in the character set for 7 programs. So if input is restricted to being in the same character set as the program, this solution is valid; but if input containing characters from outside the program's character set is allowed, this solution is invalid.

Explanation

Here's how the intended solution functions:

711170237403706 111723603700633
7   7   7                         Stack element separators
 111 023 403706 111723603700633   Initial stack elements
 111                              Number 3, in unary
     023                          I/O DSL for "input a number"
         403706 111723603700633   Main program
(Implicit: execute a copy of the main program element, preserving the original)
         40                       Swap {023} above {program}, escaping it
           3                      Do I/O using {023}; pop {program}
     0                            I/O: numeric
      23                          Input a number, copying {111} that many times
            706                   Append "6" to the number (decrementing it)
                11                Push two empty stack elements
                  17236           Push a stack element "23" (unescaped)
                       0          Escape {23}, consuming an empty element
                        3         Do I/O using {23}; pop {the element below}
                    23            Copy the top of stack input many times
                         7006     Append "66" (i.e. subtract 2)
                             3    Output {as a number}
                              3   Exit the program (due to low stack)
The leading 7 and trailing 3 aren't necessary for the program's functionality, they're just there to get the prime factors of the output right. It helps to follow this program if you understand the numeric format; numbers are stored in a unary variant in which 1 and 7 increase the value by 1, and 0 and 6 decrease the value by 1 (thus appending 66 decreases the value by 2, repeating the number multiplies it, and so on). Input's done by repeating a stack element (thus if the stack element is 12345 and the input is \$3\$, the new stack element will be \$123451234512345\$).

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

Node.js v10.9.0, 40 bytes, Score: 40, Cracked

Input

This is a function taking exactly one parameter.

Output

&`nij.9=j.,)r31n=+(=ooj`[o.o.)1.s](>=6>t
\$\endgroup\$
  • \$\begingroup\$ I can only rearrange into o=>[...j=o,].sort(n=>(j+=113)&69).join`` , but j can't go to integer \$\endgroup\$ – l4m2 Nov 6 '18 at 16:21
  • \$\begingroup\$ Cracked. That was quite fun :-) \$\endgroup\$ – ETHproductions Nov 7 '18 at 2:56
3
\$\begingroup\$

A Pear Tree, 46 bytes of ASCII, score 0, Cracked

Input is taken from standard input. The expected output (on standard output) is an empty string (i.e. when the program is given itself as argument, no output should be printed).

In other words, the challenge here is to write an A Pear Tree program that does not output anything on standard output when given itself on standard input, and which does output something on standard output when given something other than itself on standard input, using no more than 46 bytes. (I've managed to do this while holding the program to printable ASCII, too, despite A Pear Tree frequently using non-ASCII and unprintable characters.) This is effectively the task of writing a self-identifying program, with a specific output format (i.e. null string when self-identification succeeds); however, A Pear Tree has at least two twists that make the task somewhat more difficult than it looks when done in this specific language (which is why I chose it for my cop submission).

My solution

My solution is a bit different from the crack:

eval(k=q(print$\=$_="eval(k=q($k))"ne$_;MZpa))

Try it online!

Instead of using exit, I instead set $_ (implicit output) and $\ (newline after output, including implicit output) to the null string if there's a match (and to 1 if there's no match). A print is still required because implicit output is only enabled if there's at least one byte of input (thus, we need to explicitly print something if we're given an empty string as input, which is distinct from the program).

Every A Pear Tree program needs to contain a checksum somewhere (that's the MZpa in this solution). Both my solution and the crack pick variable names (and vary other minor details of the code) in order to make the checksum consist entirely of ASCII letters.

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

Perl 5 -p0777, 10 bytes, score 10, safe

W)9r46<(k

The last character here is "shift out", character code 14 (decimal) / 0E (hex). All the others are printable ASCII.

Because we're using Perl's implicit I/O argument -p0777, the input is coming from standard input, and the output going to standard output.

Solution

The program does the following:

NUL-pads the input to at least 10 characters, then XORs with the string svgOUT_TOP

which means that the program itself, the only input producing the desired output, is:

$_^=abc|$^

Try it online!

Explanation

Perl has a number of special-purpose variables. For example, when using -p0777 for implicit I/O, $_ is input at the start of the program and output at the end of the program.

Most of these variables have a very simple default value. However, the default value of $^, the currently selected top-of-page format, is the much longer string STDOUT_TOP. As such, we can use this as a very terse obfuscation method via XORing $^ with the value we want to obfuscate (in this case, the program).

In order to hide the telltale _TOP at the end, I padded the program itself out to 10 characters via adding in an abc|, meaning that all the characters of STDOUT_TOP would be XORed with something; the choice of abc| at the start was an easy way to keep the output mostly printable (and to make it harder to spot that I was XORing with a string made mostly of capital letters, because in ASCII, lowercase XOR uppercase is lowercase).

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

05AB1E, 35 bytes, Score: 7

Input:
From stdin

Output:
QÕ Ƿe

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

Cubix, 18 bytes, Score 18, safe

It's a shame that this challenge didn't get more attention, but that's the way it goes sometimes. I was going to leave this unsafe, but decided to post the solution before I forgot about it.

This should be quite easy to crack.

Input from stdin

Output

$`*2aJPJ#74(o);89

Edit: I should mention that this expects the source in it's shortened form ... and now I've noticed that there is a missing byte (unprintable) from the result that I broke when I posted. Should copy out now. The hex values are 24 60 2a 13 32 61 4a 50 4a 23 37 34 28 6f 29 3b 38 39

The concept was to remove print the first character and then remove the inverse index from the character, eg [chars]-[0,len([chars])..2]

The code is

$r;#AoW\U-@</u.?;;

which maps onto the following cube

    $ r
    ; #
A o W \ U - @ <
/ u . ? ; ; . .
    . .
    . .

Try it here

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

Jelly, 14 bytes, Score: 21, Safe

Both the program and output size are counted using Jelly codepage.

Input

First command-line argument.

Output

-§ḋẇ"*YdĖDƘ>Ẉed€Ç+æạɦ

Solution

ØJiⱮÄÆNPḃØ⁵ịØJ

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Because converting from/to Jelly codepage is hard, it would be useful to have a verifier (that takes a program, convert it from UTF8 to Jelly, feed it with itself, convert from Jelly to UTF8, and check if it's equal to the expected output) \$\endgroup\$ – user202729 Nov 7 '18 at 16:02
  • \$\begingroup\$ @user202729 this Jelly program, v⁼, will yield 1 if the input evaluated as Jelly code with an input of the input is equal to the input and will either yield 0 or error (if the input is an invalid Jelly code) if not. \$\endgroup\$ – Jonathan Allan Nov 9 '18 at 20:10
1
\$\begingroup\$

JavaScript Firefox, <10 bytes, Score: 52, from function argument input, Cracked

ZnVuY3Rpb24gYnRvYSgpIHsKICAgIFtuYXRpdmUgY29kZV0KfQ==


btoa

btoa(btoa) encodes the following string:

function btoa() {
    [native code]
}

which gives:

"ZnVuY3Rpb24gYnRvYSgpIHsKICAgIFtuYXRpdmUgY29kZV0KfQ=="

just copied

\$\endgroup\$
  • \$\begingroup\$ First of all, after doing the obvious, this isn’t actual code? Second, you don’t specify where input comes from. I would post a crack but honestly I’m not sure if this submission is valid. \$\endgroup\$ – Quintec Nov 6 '18 at 12:49
  • \$\begingroup\$ Cracked \$\endgroup\$ – Arnauld Nov 6 '18 at 15:12
  • \$\begingroup\$ I don't think it's necessary to include the crack post in this post -- people can just click the link to view the crack. \$\endgroup\$ – user202729 Nov 7 '18 at 15:35
1
\$\begingroup\$

GCC 61->61 bytes

70 4F 92 73 08 D4 03 E7 65 DC D6 89 B5 AD BA 90 
97 26 31 10 F6 FA 0A 30 8F 24 69 0A A7 8B 59 9E 
A2 42 D5 67 B8 12 3A 1E 9D 25 80 F9 6B 25 32 C2 
EE 46 3F 8D 7E 0C 73 0F F0 93 C6 68 50

Full program, take input from stdin and output to stdout

\$\endgroup\$
  • \$\begingroup\$ So, is there a space after last 50? \$\endgroup\$ – tsh Nov 8 '18 at 2:43
  • \$\begingroup\$ @tsh It's a hex dump \$\endgroup\$ – l4m2 Nov 8 '18 at 8:46
1
\$\begingroup\$

Perl 6, 43 bytes, Score: 15, from stdin

49671296789805
\$\endgroup\$
  • 2
    \$\begingroup\$ Just checking, since your previous answer didn't follow the rules on a unique output for your program as input, can you confirm that this submission does? \$\endgroup\$ – Jo King Nov 9 '18 at 3:37
  • \$\begingroup\$ Yes, I think so. \$\endgroup\$ – donaldh Nov 9 '18 at 8:59
1
\$\begingroup\$

Pepe, 23 bytes, score: 23, cracked by MickyT

Input:

standard

Output:

RDCbn@?K]<[G98765TSR^PO
\$\endgroup\$
  • \$\begingroup\$ cracked? \$\endgroup\$ – MickyT Nov 25 '18 at 22:39
1
\$\begingroup\$

J, 26 bytes, Score: 52, Safe

The program is not a REPL, but a full script that accepts stdin and explicitly prints to stdout.

Input

Standard input.

Output

6fc42353c98217ef5a2908a3c63d090aa9a55b2558b61294e06a

No, it's not an encryption method.


Solution

echo]hfd]257x#.3&u:stdin''
                   stdin'' Take the whole input
               3&u:        Convert to codepoints
         257x#.     Convert base 257 to integer
     hfd]           "Hex from Decimal"
echo]               Print to stdout

Try it online!

\$\endgroup\$
0
\$\begingroup\$

 Perl 6, 31 bytes, Score: 39, from stdin - Cracked

Cracked here

().1111111111112222235abcegijkmnorstvy

Crude solution. Might survive.

\$\endgroup\$
  • \$\begingroup\$ I'm pretty sure that I cracked your solution and I suspect that your program doesn't follow the rule that different inputs should produce different outputs. \$\endgroup\$ – nwellnhof Nov 7 '18 at 1:56

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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