9
$\begingroup$

You are a spy that wanted to find out the job of a man named John. There are 100 glasses in front of you. There is also a note:

Hello! 99 of the glasses in front of you are poisoned! One is safe, however. Just remember that you only get one try! Here's a hint, to make it easier:

VDFVXDVADXVAAVGAGXAVAVGGGGXAFGGAXGAGVVXFGAVDXGDX

Enjoy your drink, if you can!

- John

P.S. If you don't drink one, a huge elephant shall fall out of the sky and crush you to death. You have one week.

Which glass should you drink from?

$\endgroup$
  • 1
    $\begingroup$ This looks like a pretty famous cipher, but the text is definitely too short to decrypt without a key. Are you sure we have all the information we need? Is the cipher text the only relevant part, or something in the story or its wording is important too? $\endgroup$ – Aioros Aug 17 '15 at 15:52
  • $\begingroup$ @Aioros Search everywhere. The key is hidden in a method I've used on various occasions. $\endgroup$ – user9377 Aug 17 '15 at 16:11
  • $\begingroup$ @Kslkgh, I think I know the cipher and I think I know the key, but I can't for the life of me figure out what the keyword is...am I on the right track? $\endgroup$ – Bailey M Aug 17 '15 at 19:35
  • 1
    $\begingroup$ I guess the key here is "Kslkgh" / "ADFGVX"/ "John" / "JohnsRevenge" . And the cipher is ADFGVX. Am I right? Also your comment The key is hidden in a ->method<- I've used on various occasions makes me think more about key ADFGVX though it's insecure key... I will continue research after some hours because I have no time now, hope it will not get answered till then;) $\endgroup$ – Jet Aug 18 '15 at 6:52
  • 1
    $\begingroup$ Maybe keysquare is in your text? e.g. take your question, remove all repeating letters and get square? In that case I see only 3 numbers in your text 0,1,9, and probably encrypted text has a number inside. So maybe non-poisoned glass is one of 1, 9, 10, 11, 19, 90, 91, 99, 100, right? $\endgroup$ – Jet Aug 18 '15 at 7:56
5
$\begingroup$

The solution is:

youmustdrinkfromglasssix

The first step is to find the keysquare:

When looking "deeper" you can find it in the source of the question (click on "edit"): 20zsd5vt1wjipe4hfnmq8gbxy3lou6ra7k9c

I don't know if the rest of the solution is allowed (I'm new here):

I have written a program to brute force all possible transpositions, and looked for the word "glass" in the decoded text. The numeric representation of the transposition key is [6, 3, 1, 4, 0, 7, 5, 2]. This matches the word "MECHANIC" (thanks to moonbutt74).

Source code:

import java.nio.CharBuffer;
import java.util.Arrays;
import java.util.regex.Pattern;

public class JohnsRevenge {
    private static final int MAX_TRANSPOSITION_KEY_LENGTH = 10;
    private static final char[] KEYSQUARE = "20zsd5vt1wjipe4hfnmq8gbxy3lou6ra7k9c".toCharArray();
    private static final char[] CIPHER_TEXT = "VDFVXDVADXVAAVGAGXAVAVGGGGXAFGGAXGAGVVXFGAVDXGDX".toCharArray();
    private static final Pattern PATTERN = Pattern.compile("glass");

    private static int[] transpositionKey = null;
    private static int[] inverseTranspositionKey = null;
    private static char[] untransposed = new char[CIPHER_TEXT.length];
    private static char[] decoded = new char[CIPHER_TEXT.length / 2];
    private static CharBuffer buffer = CharBuffer.wrap(decoded);

    private static void untranspose() {
        int width = inverseTranspositionKey.length;
        int height = (CIPHER_TEXT.length + width - 1) / width;
        int heightChange = CIPHER_TEXT.length - (height - 1) * width;

        int cipherTextPos = 0;
        for (int x : inverseTranspositionKey) {
            int currentHeight = (x < heightChange ? height : height - 1);
            for (int y = 0; y < currentHeight; ++ y) {
                untransposed[x + y * width] = CIPHER_TEXT[cipherTextPos++];
            }
        }
    }

    private static int charToIndex(char c) {
        switch (c) {
            case 'A': return 0;
            case 'D': return 1;
            case 'F': return 2;
            case 'G': return 3;
            case 'V': return 4;
            case 'X': return 5;
            default: throw new IllegalArgumentException();
        }
    }

    private static void decode() {
        for (int i = 0; i < decoded.length; ++ i) {
            decoded[i] = KEYSQUARE[charToIndex(untransposed[i * 2]) * 6 + charToIndex(untransposed[i * 2 + 1])];
        }
    }

    private static void check() {
        if (PATTERN.matcher(buffer).find()) {
            System.out.println(buffer + " " + Arrays.toString(transpositionKey));
        }
    }

    private static void generateKeys(int pos) {
        outer:
        for (int i = 0; i < transpositionKey.length; ++ i) {
            for (int j = 0; j < pos; j ++) {
                if (i == transpositionKey[j]) {
                    continue outer;
                }
            }
            transpositionKey[pos] = i;
            inverseTranspositionKey[i] = pos;
            if (pos < transpositionKey.length - 1) {
                generateKeys(pos + 1);
            } else {
                untranspose();
                decode();
                check();
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 1; i <= MAX_TRANSPOSITION_KEY_LENGTH; ++ i) {
            System.out.println("[" + i + "]");
            transpositionKey = new int[i];
            inverseTranspositionKey = new int[i];
            generateKeys(0);
        }
    }
}
$\endgroup$
  • $\begingroup$ That's neat! If i didn't still have an elephant on top of me, i'd shake your hand! You absolutely should post the complete solution. +1 I had tried mechanic but without the table it meant nothing. @Kslkgh ,that's sneaky. =D $\endgroup$ – moonbutt74 Aug 18 '15 at 16:26
  • 1
    $\begingroup$ @moonbutt74 I have added the source code, and added more info in the third spoiler. Your transposition key is correct. $\endgroup$ – Sleafar Aug 18 '15 at 19:36
  • $\begingroup$ thanks, i've been playing with this , do you have a version that will accept user input for the all the variables, i tried to patch in the scan function but i suck. xD If that's ok/doable can you link me to your git? Thanks. $\endgroup$ – moonbutt74 Aug 19 '15 at 3:16
  • 1
    $\begingroup$ @moonbutt74 I don't have a public repository yet, and this code was just a quick and dirty solution. Instead of using the Scanner you can pass the values as arguments, like: int keyLength = Integer.valueOf(args[0]);. $\endgroup$ – Sleafar Aug 19 '15 at 5:20
0
$\begingroup$

OK, continuing the research I want to tell some facts:

1) Before permutating (rearranging) columns with key, free squares are filed with letter X, for example:

    K   E   Y               K   E   Y
1   F   A   G          1    F   A   G
2   V   D   F    <=>   2    V   D   F
3   F   A   A          3    F   A   A
4   F                  4    F   X   X

This means the final encrypted text length will be divisible by key length.
In this example length is 12 and key has 3 letters.
Now we our ciphertext's length is 48
VDFVXDVADXVAAVGAGXAVAVGGGGXAFGGAXGAGVVXFGAVDXGDX
123456789012345678901234567890123456789012345678
It means we have several possible key lengths, as 48 is divisible by:

1, 2,             - Hardly possible
3, 4, 6, 8, 12,   - Possible
16, 24, 48        - Hardly possible

Of which most probably key length is 3, 4, 6, 8, 12.
Maybe now we should find words with this lengths:

JohnsRevenge - 12  
John - 4
Kslkgh ?- 6
ADFGVX - 6
etc

2) Empty boxes are filled with X. It means that last row can have more X-es, because count of X on last row doesn't change even after permutation.

Also probablity of X* pair the least, because usually all unused letters/numbers are in X row (in non-permutated ciphertext).

    A   D   F   G   V   X
    ...
V   B   N   0   1   2   3 
X-> 4   5   6   7   8   9  - symbols in this row are used rarely, so X* is rare 

Back to the game. When trying all possible key lengthes (write cipher VDFVX... upside down, left to right, in 3, 4, 6, 8, 12 columns) the more X-es we have on the last row the more possibility is that we have found the correct key length. (It's about possibility, not 100% correct)

3) Not a fact but interesting:
@Kslkgh, I think I know the cipher and I think I know the key, but I can't for the life of me figure out what the keyword is...am I on the right track?

@BaileyM Do you mean that you know what the ->keysquare<- is. If you do, you are definately on the right track! – Kslkgh
Seems like he the OP reacted more on keysquare (and doesn't care about permutation key?). So probably key is obvious/easy to find.
Also The key is hidden in a ->method<- I've used on various occasions – Kslkgh again makes me think the key is method name- ADFGVX (also it's length is equal to 6, and 48 is divisible by 6).

TO BE CONTINUED...

$\endgroup$

Your Answer

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