Cheapo Enigma machine (Robbers)

8

For cops' post, Cheapo Enigma machine (Cops)

A robber's submission consists of a program/function that accepts the output of a cop's code and returns the input for all the outputs provided by that cop's code. (In other words, you must write the inverse function)

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

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 must belong to the same range (as in, binary, 1-256, 0-255 or -128 to 127), which must also be the same range as that used by the cop.

Scoring

Ratio of the cop's byte count to your byte count. Highest score wins.

You can submit a robber attempt against your own cop code for reference. (Of course this code isn't eligible for winning)

Notification

Please edit the corresponding cop's answer to include your new byte count and the corresponding ratio.

ghosts_in_the_code

Posted 2017-04-22T10:14:21.237

Reputation: 2 907

2At first I was wondering how you were going to make Emigna into a machine. Then I realized you weren't talking about the user. – Magic Octopus Urn – 2017-04-24T18:39:31.733

OK, sorry for bothering you again, but I want to make sure I got it right this time. If the brainfuck answer reads and prints bytes (code points 0 to 255) and my Jelly answer takes an integer between 0 and 255 and returns an integer in the same range, is that acceptable? – Dennis – 2017-04-28T15:32:19.453

@Dennis No, it isn't. Maybe you (or someone else) could suggest an alternate wording that makes this clearer. – ghosts_in_the_code – 2017-04-28T16:12:34.177

@carusocomputing Emigna is a machine, right? He has every single 05AB1E program loaded up in his memory system, yeah? – caird coinheringaahing – 2017-06-18T23:17:28.547

Answers

3

JavaScript by Christoph, 8/25

f=(y,x=0)=>y?f(y/2,x^y):x

(range 0-255)

Sadly, f=(y,x)=>y?f(y/2,x^y):x works for all values except 0.

Technical note

We use y/2 rather than y>>1 to save a byte. This is abusing the fact that any value of y will eventually be rounded to 0 because of arithmetic underflow.

Arnauld

Posted 2017-04-22T10:14:21.237

Reputation: 111 334

2

JavaScript by fəˈnɛtɪk, 13/19

x=>((514>>x%2)-x)/2

(range 1-256)

Arnauld

Posted 2017-04-22T10:14:21.237

Reputation: 111 334

2

C, by Dave, 64/95 92 85

b,i,e,t[256];r(x){for(;!b;++i,b=e==x)for(srand(i&&e);t[e=rand()%256]++;);return i-1;}

Try it here!

C, shorter version, 64/89 71

i,e,t[256];r(x){for(srand(1);t[e=rand()%256]++||++i,e!=x;);return i-1;}

This one is more implementation specific, but works on TIO. Same length as the PHP solution, I wasn't able to get it any shorter than this.

Try it here!

Appleshell

Posted 2017-04-22T10:14:21.237

Reputation: 121

Ok I will take it up with the cops submission then. Thanks for informing me. – Post Rock Garf Hunter – 2017-04-28T05:05:23.157

1

Javascript by histocrat, 27 / 29

x=>x-65?x-126?x*127%258:131:6

Sadly two hard codings are needed in order to break it. Note that the orginal function doesn't map any value to 130 but maps a value to 256.

Christoph

Posted 2017-04-22T10:14:21.237

Reputation: 1 489

1Having 256 in the range is legal according to the rules ("8 bits (0 or 1), or a base-10 integer in range 1-256"). This is still a valid Robber on that range, though! – histocrat – 2017-04-25T13:05:36.463

1

JavaScript by fəˈnɛtɪk, 13 / 12

x=>x*128%257

Another multiplicative inverse.

Christoph

Posted 2017-04-22T10:14:21.237

Reputation: 1 489

1

JavaScript, 11/13

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

Try it online!

fəˈnɛtɪk

Posted 2017-04-22T10:14:21.237

Reputation: 4 166

1

Jelly, 22/3 = 7 1/3

⁹ḶDÞḊi

Try it online!

The cop submission by fəˈnɛtɪk was to return the nth (0-indexed) lexicographically sorted decimal number using the domain [0,255].

I first literally reversed the operation described, ⁹ḶDÞi⁸‘ - takes the lowered range of 256, ⁹Ḷ, and Þ instructs to sort it by a key function of conversion to a decimal list, D; then finds the index of, i, the input, , and subtracts 1, (Jelly lists are 1-indexed).

Then I golfed it by dequeuing the sorted list with . When an item is not found i returns 0 as required for the removed first element (0), while everything else is found one index earlier, allowing the removal of the decrement, , which in turn gives i implicit input on its right from the left (only) input to the monadic link.

Jonathan Allan

Posted 2017-04-22T10:14:21.237

Reputation: 67 804

1

Javascript by Magenta, 32 / 23

x=>x%16*16+(x/16+13)%16

Code basically switches the lower and the upper 4 bits and does a modulo addition on one part.

Christoph

Posted 2017-04-22T10:14:21.237

Reputation: 1 489

1

PHP, Score 64/71

for(srand(0);$a<256;)$b[$c=rand()%256]++||$d[$c]=$a++;echo$d[$argn]|0;

Luckily PHP's rand just forwards to the stdlib like C. So this works as long as we're using the same stdlib. This means it works on TIO but not on e.g. sandbox.onlinephpfunctions.com. The current version of Dave's code just iterates over a pseudorandom sequence and returns the nth unique value so I guess there might be much shorter answers if a golfing languages also uses the stdlib.

Here's an implementation of Dave's code that does not dependent on the stdlib. That might also help.

Christoph

Posted 2017-04-22T10:14:21.237

Reputation: 1 489

+1 for finding a way to switch language on this one! Any idea why this doesn't need to srand(1)? Also here's a Try it online!

– Dave – 2017-04-28T12:10:09.447

@Dave srand(x&&f(x-1)) this stops only if x==0 therefore it gets seeded with 0 on the first round. Not sure why the next calls don't change it. – Christoph – 2017-04-28T12:47:02.143

@Dave it seems srand(0) breaks rand (see here). I guess srand(0) automatically gets promoted to srand(1). I guess if you could use a different seed each time it would get a lot harder to break it.

– Christoph – 2017-04-28T12:55:50.637

Interesting that this works. Seems to be specific to the stdlib version used on TIO, the behaviour in C on there is apparently the same, while on my local machine with clang it requires to re-invoke srand with 0 resp. 1 on each iteration, instead of just invoking it once with 0. – Appleshell – 2017-04-28T18:02:30.440

1

@Appleshell seems Christoph's suspicions are correct: glibc has a special check. See here: http://stackoverflow.com/a/8049852/1180785 (since you mention clang, I'm guessing your local is OSX, so no glibc)

– Dave – 2017-04-28T18:09:28.173

0

Octave, 16/18

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

Try it online!

flawr

Posted 2017-04-22T10:14:21.237

Reputation: 40 560

0

Jelly, 2/5 (non-competing)

^H$7¡

Try it online to see the whole table.

Dennis

Posted 2017-04-22T10:14:21.237

Reputation: 196 637

0

Jelly, 8/5

^H$7¡

Try it online to see the whole table.

Dennis

Posted 2017-04-22T10:14:21.237

Reputation: 196 637

0

Jelly, 16/6

×171%⁹

Try it online to see the whole table.

Dennis

Posted 2017-04-22T10:14:21.237

Reputation: 196 637

0

Jelly, 11/8

*205%257

Try it online to see the whole table.

In case robber submissions in a different languages are disallowed in the future, I call dibs on the following solution.

g=(x,y=0)=>x-++y**5%257?g(x,y):y

Dennis

Posted 2017-04-22T10:14:21.237

Reputation: 196 637

0

Jelly, 37/11

O_77×191%⁹Ọ

Uses the same I/O format as the cop. Not sure if that is required.

Try it online to see the whole table.

How it works

For input n, the cop answer computes f(n) := ((((n + 5) % 256 × 2) % 256 + 2) % 256 × 9) % 256. Since % is a linear operator, this is equivalent to f(n) = (((n + 5) × 7 + 2) × 9) % 256. Expanding the right term, we get f(n) = (63n + 333) % 256 = (63n + 77) % 256.

Reversing this is rather straightforward. To undo the addition, we simply have to subtract 77. Also, since 191 × 63 % 256 = 12033 % 256 = 1, it follows that 191 is 63's inverse modulo 256, so multiplying by 191 undoes multiplying by 63. This way, g(n) = (n - 77) × 191 % 256 defines the inverse of f.

Dennis

Posted 2017-04-22T10:14:21.237

Reputation: 196 637

0

Jelly, 35/7

⁹Ṗ+\%⁹i

Try it online to see the whole table.

Dennis

Posted 2017-04-22T10:14:21.237

Reputation: 196 637

0

C (gcc) by Bijan, 32 / 30

g(x){x=x?g(--x)*205+51&255:0;}

Had a fun time golfing it, thanks ! x= allows to skip return with gcc and tcc (you might want to change your answer to include it). g(--x)*205+51&255 is the inverse.

Christoph

Posted 2017-04-22T10:14:21.237

Reputation: 1 489