pub fn hil_xy_from_s(ip_as_int: u32, order: i16) -> (u32, u32)
Expand description

Convert an IPv4 address (in integer form) to a 12th order Hilbert x/y point

This is a funky state-transition table made (in)famous? in “The Hacker’s Delight”.

The license is quite generous, if not adorable by today’s standards. Do not try to visit the site today as spammers nabbed the domain.

In any Hilbert curve, only four of eight possible U-shapes occur:

  • (A) left-to-right arrow downward facing
  • (B) bottom-to-top arrow leftward facing
  • (C) right-to-left arrow upward facing
  • (D) top-to-bottom arrow rightward facing

In this program, the current state is represented by an integer from 0 to 3 for the above states A through D, respectively. In the assignment to row, the current state is concatenated with the next two bits of s, giving an integer from 0 to 15, which is the applicable row number in the state table (below). row is used to access integers (expressed in hexadecimal) that are used as bit strings to represent the rightmost two columns of the state table (that is, these accesses are in-register table lookups). Left-to-right in the hexadecimal values corresponds to bottom-to-top in the state table.

If the
current
state is
and the
next (to right)
2 bits of s are
then
append
to (x,y)
and
enter
state
A00(0,0)B
A01(0,1)A
A10(1,1)A
A11(1,0)D
B00(0,0)A
B01(0,1)B
B10(1,1)B
B11(1,0)C
C00(0,0)D
C01(0,1)C
C10(1,1)C
C11(1,0)B
D00(0,0)C
D01(0,1)D
D10(1,1)D
D11(1,0)A

Original C code:

void hil_xy_from_s(unsigned s, int n, unsigned *xp, unsigned *yp) {
  int i;
  unsigned state, x, y, row;
  state = 0; // Initialize state
  x = y = 0;
 
  for (i = 2*n - 2; i >= 0; i -= 2) {  // Do n times.
    row = 4*state | (s>>i) & 3;        // Row in table. 
    x = (x << 1) | (0x936C >> row) & 1;
    y = (y << 1) | (0x39C6 >> row) & 1;
    state = (0x3E6B94C1 >> 2*row) & 3; // New state.
  }
 
  *xp = x; // pass results back
  *yp = y;
}

Grab the book for a few more alternative implementations.