16
\$\begingroup\$

For robbers' post, Cheapo Enigma machine (Robbers)

A cop's submission will consist of a program/function that accepts a single byte of data and return a single byte of data. Every possible input must produce a unique output. (In the other words, your function must be bijective)

Robbers will attempt to create the inverse function of yours using as short a code as possible. So your objective is to make your function difficult to invert.

You cannot use built-ins that have the sole purpose of hashing or encryption.

Your byte count cannot exceed 64 bytes. 0-byte solutions are not eligible for winning.

Input/Output format

8 bits (0 or 1), or a base-10 integer in range 1-256, 0-255 or -128 to 127. Can use standard I/O or file I/O. Function can also return a value as output. Input and output should belong to the same range (binary, 1-256, 0-255 or -128 to 127). The robber will also be required to use this range for input and output.

Scoring

Ratio of your byte count to that of the best robber's attempt against you. Lowest score wins.

You are eligible to win (as a cop) only if a robber has attempted to defeat you. (This robber may be you)

Example

C++, uses 0-255 range, 31 bytes

int x;
cin>>x;
cout<<(x+1)%256;

Possible robber submission in C++, 32 bytes

int f(int x)
{return x?x-1:255;}

Using the same language or a similar algorithm isn't a requirement

This gives a score of 31/32 = 0.97 to both the cop and the robber.

\$\endgroup\$
16
  • 1
    \$\begingroup\$ What does a cop submission consist of? Language, size and full program/function code? \$\endgroup\$
    – Arnauld
    Apr 22, 2017 at 10:27
  • 1
    \$\begingroup\$ isn't it a bit broken if the cop can just make an arbitrarily large thing? \$\endgroup\$ Apr 22, 2017 at 10:32
  • 1
    \$\begingroup\$ This robber may be you What if I post a 64-byte cop answer that maps N to N and a robber answer that does the same thing in one byte? \$\endgroup\$
    – Arnauld
    Apr 22, 2017 at 11:04
  • 1
    \$\begingroup\$ You may want to specify if / how the cop submission should be updated when robbers answer it. (The usual "cracked" update doesn't apply here, I guess. At least not as a unique and definitive crack.) \$\endgroup\$
    – Arnauld
    Apr 23, 2017 at 13:28
  • 3
    \$\begingroup\$ On second thought, you might want to remove that rule altogether. I can destroy most answers by posting a robber in Jelly. \$\endgroup\$
    – Dennis
    Apr 24, 2017 at 18:25

15 Answers 15

7
+50
\$\begingroup\$

Javascript, 11 8 bytes, Score: 8 / 5

x=>x^x/2

Simple implementation of gray code. Decoding usally needs a whole loop. Let's see who comes up with the smallest or even without a loop !

\$\endgroup\$
7
  • \$\begingroup\$ I guess x^x/4 will be harder because there shouldn't be builtins for it ... \$\endgroup\$
    – Christoph
    Apr 24, 2017 at 8:31
  • 1
    \$\begingroup\$ Score: 8/25 \$\endgroup\$
    – Arnauld
    Apr 24, 2017 at 8:36
  • 1
    \$\begingroup\$ How is this bijective? \$\endgroup\$
    – Leaky Nun
    Apr 25, 2017 at 11:54
  • 1
    \$\begingroup\$ @LeakyNun Uhm not sure what kind of an answer you expect but I'll try: Gray code is an alternative form of representing a number where each consecutive number only changes in 1 bit (hammig distance is always 1). For each number there is exactly one gray encoding and one binary encoding therefore they form a bijection. E.g. 7 is 0111 in binary and 0100 in gray, the next number 8 is 1000 in binary and 1100 in gray. Gray coding is basically the edge coding of binary. \$\endgroup\$
    – Christoph
    Apr 25, 2017 at 13:56
  • 1
    \$\begingroup\$ @LeakyNun ^ is bitwise xor, not exponentiation. Anyway it looks magic \$\endgroup\$ Jul 25, 2017 at 11:45
7
\$\begingroup\$

C, 64 bytes, Score 64/71 = 0.901

T[256];f(x){srand(x&&f(x-1));for(;T[x=rand()%256]++;);return x;}

Takes input in the range [0 255].

Try it online! — on TIO (using GCC), this produces:

103,198,105,115,081,255,074,236,041,205,186,171,242,251,227,070,
124,194,084,248,027,232,231,141,118,090,046,099,051,159,201,154,
102,050,013,183,049,088,163,037,093,005,023,233,094,212,178,155,
180,017,014,130,116,065,033,061,220,135,112,062,161,225,252,001,
126,151,234,107,150,143,056,092,042,176,059,175,060,024,219,002,
026,254,067,250,170,058,209,230,148,117,216,190,097,137,249,187,
168,153,015,149,177,235,241,179,239,247,000,229,202,011,203,208,
072,071,100,189,031,035,030,028,123,197,020,075,121,036,158,009,
172,016,080,021,111,034,025,125,245,127,164,019,181,078,152,224,
077,052,188,095,119,108,134,043,085,162,004,211,054,226,240,228,
079,073,253,169,008,138,010,213,068,091,243,142,076,215,045,066,
006,196,132,173,222,048,246,032,133,007,244,185,195,217,160,120,
218,106,083,144,087,238,207,096,210,053,101,063,098,128,165,089,
140,012,192,131,047,039,022,147,184,109,182,193,199,237,018,069,
057,157,174,104,122,166,055,110,003,040,139,086,145,114,129,113,
206,167,191,214,146,221,136,038,156,082,200,029,044,204,223,064

Note that on other systems, it may produce different (but still valid) output, since C does not mandate a specific rand implementation. My submission is specifically the version running on TIO (as linked).


I'm quite disappointed that I wasn't able to get a version like my original (f(x){return rand(srand(x*229))/229%256;}) to work on TIO, since I think that's much more elegant. Since that only works on Clang running on OS X, it isn't fair for the competition. This one's still pretty awkward to reverse, so that's enough I guess.

\$\endgroup\$
12
  • \$\begingroup\$ Well..This is amusing! \$\endgroup\$ Apr 27, 2017 at 13:38
  • \$\begingroup\$ Solution here, but I had a bit of a hard time with your srand(), so you'll have to decide if it's acceptable in this form. \$\endgroup\$
    – Appleshell
    Apr 28, 2017 at 4:41
  • \$\begingroup\$ I fail to see how this program fulfills the Bijection requirement, since output is random not every input has a unique output. \$\endgroup\$
    – Wheat Wizard
    Apr 28, 2017 at 5:08
  • 2
    \$\begingroup\$ The problem is not the implementation. The problem is that it lacks what I think are all key ideas of this challenge: Finding a trival algorithm (therefore limited to 64 bytes and language independent) that is nontrival to reverse. Your submission "feels" to loophole on: Language independence, the 64 byte limit by outsourcing to an unknown implementation of a builtin (rand does not depend on the language but the local stdlib) and the hash/encryption rule. It's within PPCG's rules but certainly not what ghosts_in_the_code intended with his rules. \$\endgroup\$
    – Christoph
    Apr 28, 2017 at 8:24
  • 1
    \$\begingroup\$ @ghosts_in_the_code good RNGs and hash functions are both designed to hardly be reversible. Therefore I think they should be included in that rule (even if the actual implementation might not be designed this way). Anyway I don't recommand changing the rules at this stage. \$\endgroup\$
    – Christoph
    Apr 28, 2017 at 10:54
2
\$\begingroup\$

Jelly, 2/5

^H

Try it online to see the whole table.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Hm, looks like @Christoph had the same idea 9 hours before me... \$\endgroup\$
    – Dennis
    Apr 24, 2017 at 17:50
2
\$\begingroup\$

JavaScript, 44 bytes 22/3

x=>a.sort()[x]
for(a=[],i=0;i<256;)a[i]=i++;

Uses lexicographic sort (Javascript Default) to rearrange all the numbers from 0-255

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 22/3 - different language seems acceptable, even if a little odd. I thought I had 5, but 256 got in my way :). \$\endgroup\$ Apr 26, 2017 at 4:16
2
\$\begingroup\$

C (gcc), 32 27/30 bytes

Thanks to christoph for golfing 5 bytes.

f(x){x=x?f(x*5+1&255)+1:0;}

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Score 32/30. You might want to switch to f(x){x=x?f(x*5+1&255)+1:0;} for a score of 27/30. \$\endgroup\$
    – Christoph
    Apr 28, 2017 at 14:39
1
\$\begingroup\$

Javascript, 11/8 bytes

x=>x**5%257

Domain/range is 1 through 256.

\$\endgroup\$
6
  • \$\begingroup\$ Hm, is Javascript bad with large number exponents? This works in Ruby: repl.it/HXvZ/0 \$\endgroup\$
    – histocrat
    Apr 24, 2017 at 19:00
  • \$\begingroup\$ JavaScript only has double-precision floats, so anything with more than ~53 bits cannot be represented exactly. x**3 and x**5 should work. \$\endgroup\$
    – Dennis
    Apr 24, 2017 at 19:02
  • \$\begingroup\$ Well, serves me right for assuming. I'll change languages. \$\endgroup\$
    – histocrat
    Apr 24, 2017 at 19:03
  • \$\begingroup\$ Or do Dennis's suggestion, given the rules favoring terser languages. :) Thank you! \$\endgroup\$
    – histocrat
    Apr 24, 2017 at 19:05
  • \$\begingroup\$ Unfortunately, the rules are a bit broken at the moment, and I would be allowed to invert this with another language. Precisely because of the precision limit, this will be rather verbose to invert using JS. \$\endgroup\$
    – Dennis
    Apr 24, 2017 at 19:08
1
\$\begingroup\$

JavaScript, 13 bytes 13/12

x=>(x<<9)%257

Input and output are both in the range 1->256

Try it online!

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

Javascript, 27/29 bytes

x=>x-6?x*95%127+x*98%131:65

Edit: Range/Domain is 1..256. Generated via brute force, more or less.

\$\endgroup\$
3
  • \$\begingroup\$ Sadly it's bijective but not in range [0,256): the value of 130 is never outputted but a value of 256 is (which doesn't fit a 8 bit int). \$\endgroup\$
    – Christoph
    Apr 25, 2017 at 6:27
  • \$\begingroup\$ Score 27 / 29. I like it ! \$\endgroup\$
    – Christoph
    Apr 25, 2017 at 6:28
  • 1
    \$\begingroup\$ Thanks! The rules allow me to specify a range of [1,256], and it's bijective on that range. \$\endgroup\$
    – histocrat
    Apr 25, 2017 at 13:01
1
\$\begingroup\$

Octave, 16/6

@(x)mod(x*3,256)

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Score: 16/6 (Note: I don't think it should be allowed to use another language for the robber submission, but at this point, it is.) \$\endgroup\$
    – Dennis
    Apr 24, 2017 at 18:42
  • 1
    \$\begingroup\$ It would also be interesting to know whether I can try to beat your robber submission by making another cop (again using Jelly or MATL too) \$\endgroup\$
    – flawr
    Apr 24, 2017 at 19:49
1
\$\begingroup\$

Java, 35 bytes

int a(int v){return (v*v+v)%512/2;}

Domain/Range are 0-255

\$\endgroup\$
1
1
\$\begingroup\$

Ruby, 23 bytes

->x{('228'*x).to_i%257}

Range and domain is 0..255. Concatenate 228 to itself x times, then take the result modulo 257 (0 maps to 0). 228 is the first magic number after 9 that works for this range (gives distinct values that don't include 256).

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

Python 3, 55 bytes

y=lambda x,i=3:x if i==0 else pow(3,y(5*x,i-1),257)-1

Domain/Range is 0-255.

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

Python 3, 32 bytes 32/23

V=lambda x:((3+x)%16)*16+x//16

Domain/Range is 0-255.

Flips the first four bytes with the last four, and adds a three to the first bytes.

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

Mathematica, 13 bytes

Mod[#^7,257]&

Uses the range [1..256], although it's equally valid on the range [0..255]. To see the entire table, copy/paste one of the following lines of code into the Wolfram sandbox:

Array[ Mod[#^7,257]&, 256]   (for a list of values in order)
Array[ Rule[#,Mod[#^7,257]]&, 256]   (for a list of input-output rules)
\$\endgroup\$
0
\$\begingroup\$

brainfuck, 37/11

,+++++[>+++++++<-]>++[<+++++++++>-]<.

Try it online!

Not very good but range of 0-255

\$\endgroup\$
4
  • \$\begingroup\$ Score: 37/11 \$\endgroup\$
    – Dennis
    Apr 27, 2017 at 16:40
  • \$\begingroup\$ @Dennis Nice job! I should not use such a bytey language. \$\endgroup\$
    – user63187
    Apr 27, 2017 at 21:43
  • 3
    \$\begingroup\$ By the way, censoring language names isn't a good idea. Yes, this particular languages has an ordinary and childish name, but everyone knows what the asterisk stands for, and it cannot be found by the search engine in its current form. \$\endgroup\$
    – Dennis
    Apr 27, 2017 at 21:46
  • \$\begingroup\$ @Dennis finally fixed that \$\endgroup\$
    – user63187
    May 28, 2017 at 20:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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