Hacker News new | past | comments | ask | show | jobs | submit login

I did some fooling around with this and it seems promising.

The first problem is that, when your enciphering function is a matrix, f(0) = 0. This looks bad, but we can easily solve that problem by starting the webpage sequence at an index higher than 0.

I tried to work through a much smaller version of the problem* by hand, and it looks like this:

We have our enciphering matrix N:

    [[1 1 1 1 1]
     [1 0 0 1 1]
     [1 1 1 0 0]
     [0 1 1 1 0]
     [1 0 1 0 0]]
and our deciphering matrix D, the inverse of N:

    [[1 1 1 0 0]
     [0 0 1 0 1]
     [1 1 1 0 1]
     [1 1 0 1 0]
     [0 1 1 1 0]]
We want to find the next index whose encipherment ends in -110. This sets up a system of equations Dx = y, where x_3 = 1, x_4 = 1, x_5 = 0, and y tells us the index of x. By multiplying that out, we get:

    y_1 = x_1 + x_2 + 1
    y_2 = 1
    y_3 = x_1 + x_2 + 1
    y_4 = x_1 + x_2 + 1
    y_5 = x_2
So we can freely choose any values for y_1 and y_5, and the rest will be filled in by constraints.

Assuming we want the least possible value for y, this means we will pick y_1 = 0 and y_5 = 0, which then tells us that we want index [0 1 0 0 0], and we can jump to there. If we wanted the least possible value for y above a threshold (such as the current viewport), we'd pick y_n values accordingly.

Instinct tells me that libraries should exist for quickly solving systems of linear equations like this.

(For full full-text search, we'd need to do this several times, also finding solutions for the enciphered values 110xx, and x110x. This multiplies the work we need to do and the storage we need to use by an amount that is linear in the difference in length between the search string and the full UUID, which is still a lot better than trial-and-error.)

* I ended up doing it in 5 bits because every random 4x4 matrix I generated was noninvertible.




Following up, using this encipherment scheme and starting from a 5-bit seed of 17, you produce values in this sequence:

5, 7, 31, 10, 18, 16, 8, 11, 19, 17, 9, 28, 4, 6, 30, 0, 24, 26, 2, 23, 15, 13, 21, 22, 14, 12, 20, 1, 25, 27, 3, 29.

This might pass an eyeball test for random when viewed as decimal numbers. (Although there sure are a lot of cases where adjacent values are 2 apart!) It looks much worse as binary. Here's every ones digit, all concatenated into a hex string, starting from 17 again:

    e1e01e1f
Let's note that ~(e1e0) = 1e1f. Start from 16 instead and you'd see f0f00f0f. Here are the eights:

    3332bbbc
Individual bits show pretty striking patterns. Since the UUID is reported in hex, that can be mitigated a little by the fact that each hex digit combines four binary columns. But so far it seems pretty likely that this would result in the list of UUIDs looking decidedly nonrandom. There might be quite a bit of shared material between adjacent UUIDs.


correction: the run of the eights is 3332cccd, not 3332bbbc.


Can you solve this in general without doing integer linear programming? How else would you know how to find the lowest index greater than the current? In the field GF(2), using 0 might not minimize.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: