views:

43

answers:

0

Hi everyone. Couple of years ago i found a space filling curve implementation (Hilbert's) written in C designed to plot IP addresses. (I can't seem to find it again). I would like to convert this into PHP, returning a coordinate on an arbitrary grid.

I found this question that is very related.

This is a longshot, but i figured someone who is interested in this too can help me convert it into PHP, I can see many uses for it:

#define _GNU_SOURCE I_LOVE_RMS
#include <stdio.h>
#include <string.h>
#include "fnt6x11.h"
#include "xmap.h"

#define MAXBITS 11

int bits = 10;
int tabx[1<<(2*MAXBITS)],taby[1<<(2*MAXBITS)];
unsigned bg[1<<MAXBITS][1<<MAXBITS];
int stat[1<<MAXBITS][1<<MAXBITS];

void bgp(int x, int y, unsigned c)
{
    if(x<0 || y<0 || x>=1<<MAXBITS || y>=1<<MAXBITS)
    return;
    bg[x][y]=c;
}

void draw_ch(int x, int y, unsigned char ch, unsigned c, int s)
{
    int i,j,si,sj;
    unsigned char *p=font6x11+(11*ch);
    for(j=0;j<11;j++) {
    for(sj=0;sj<s;sj++)
        for(i=0;i<6;i++)
        if((*p<<i)&128)
            for(si=0;si<s;si++)
            bgp(x+i*s+si, y+j*s+sj, c);
        else
            for(si=0;si<s;si++)
            bgp(x+i*s+si, y+j*s+sj, 0);
    p++;
    }
}

void draw_str(int x, int y, int w, int h, unsigned char *str, unsigned c, int s, int j)
{
    char *sd = strdupa((char *)str), *p = sd, *q, *lq;
    int nl = 1, pl = 0, px, py;
    while(*p) {
    q=strchr(p, ' ');
    lq=q;
    while(q && (q-p)*6*s<w) {
        lq=q;
        q=strchr(q+1, ' ');
    }
    if(lq) {
        *lq=0;
        p=lq+1;
        nl++;
    } else
        break;
    }
    p = sd;
    py = y+(h-11*s*nl)/2;
    for(pl=0; pl<nl; pl++) {
    if(j)
        px = x+(w-6*s*strlen(p))/2;
    else
        px = x;
    for(; *p; p++) {
        draw_ch(px, py, *p, c, s);
        px += 6*s;
    }
    p++;
    py += 11*s;
    }
}

int i;
void recurse(int x, int y, int a, int level)
{
    int s;
    if(level == 0) {
    tabx[i] = x;
    taby[i] = y;
    i++;
    return;
    }
    level--;
    s = 1<<level;
    switch(a) {
    case 0:
    recurse(x,   y,   1, level);
    recurse(x,   y+s, 0, level);
    recurse(x+s, y+s, 0, level);
    recurse(x+s, y,   3, level);
    break;
    case 1:
    recurse(x,   y,   0, level);
    recurse(x+s, y,   1, level);
    recurse(x+s, y+s, 1, level);
    recurse(x,   y+s, 2, level);
    break;
    case 2:
    recurse(x+s, y+s, 3, level);
    recurse(x+s, y,   2, level);
    recurse(x,   y,   2, level);
    recurse(x,   y+s, 1, level);
    break;
    case 3:
    recurse(x+s, y+s, 2, level);
    recurse(x,   y+s, 3, level);
    recurse(x,   y,   3, level);
    recurse(x+s, y,   0, level);
    break;
    }
}

void draw_ip(int i0, int i1, int i2, int i3, char *name)
{
    int x, y, i;
    unsigned lin, ptr;
    lin=(((((i0<<8)|i1)<<8)|i2)<<8)|i3;
    ptr=lin>>(32-bits*2);
    x = tabx[ptr];
    y = taby[ptr];
    for(i=-5;i<=5;i++) {
    bgp(x, y+i, 0xC0FFC0);
    bgp(x+i, y, 0xC0FFC0);
    }
    if(bits>=10 && name)
    draw_str(x+3, y+3, 1024, 11, name, 0xA0FFA0, 1<<(bits-10), 0);
}

int main(int argc, char *argv[])
{
    int ip[4], x, y, g, i, j, k;
    int txt[256];
    unsigned char c[3], name[16], *fin=NULL, *fout=NULL, *fp;
    unsigned lin, ptr;
    j=0;
    for(i=1; i<argc; i++) {
    if(argv[i][0]=='-') {
        if(argv[i][1]=='s')
        j=1;
        if(argv[i][1]=='m')
        j=2;
    } else if(j==1) {
        bits = strtol(argv[i], &fp, 0);
        if(*fp || !*argv[i]) {
            fprintf(stderr, "Usage: xmap [options:-s,-m] <IP list file> <output PPM file>\n");
            fprintf(stderr, "       -s <bits> - set size to 2^bits x 2^bits\n");
            return 1;
        }
        if(bits > MAXBITS) {
            fprintf(stderr, "Usage: xmap [options:-s,-m] <IP list file> <output PPM file>\n");
            fprintf(stderr, "       -s <bits> - set size to 2^bits x 2^bits\n");
            fprintf(stderr, "       This build supports up to %d bits - change MAXBITS and recompile\n", MAXBITS);
            return 1;
        }
        if(bits < 5) {
            fprintf(stderr, "Usage: xmap [options:-s,-m] <IP list file> <output PPM file>\n");
            fprintf(stderr, "       -s <bits> - set size to 2^bits x 2^bits\n");
            fprintf(stderr, "       Minimum value is 5 (32x32 map)\n");
            return 1;
        }
        j=0;
    } else if(!j) {
        if(fin) {
        if(fout) {
            fprintf(stderr, "Usage: xmap [options:-s,-m] <IP list file> <output PPM file>\n");
            return 1;
        }
        fout = argv[i];
        } else
        fin = argv[i];
    } else
        j=0;
    }
    if(!fin || !fout) {
    fprintf(stderr, "Usage: xmap [options:-s,-m] <IP list file> <output PPM file>\n");
    return 1;
    }
    FILE *f=fopen(fin,"r");
    if(!f) {
    fprintf(stderr, "Usage: xmap [options:-s,-m] <IP list file> <output PPM file>\n");
    fprintf(stderr, "       cannot open IP list file\n");
    return 1;
    }
    g=1<<(bits-4);
    recurse(0, 0, 0, bits);
    while(fscanf(f, "%d.%d.%d.%d",ip,ip+1,ip+2,ip+3)==4) {
    lin=(((((ip[0]<<8)|ip[1])<<8)|ip[2])<<8)|ip[3];
    ptr=lin>>(32-bits*2);
    stat[tabx[ptr]][taby[ptr]]++;
    }
    fclose(f);
    if(bits>9) {
    for(i=0;i<256;i++)
        txt[i] = 1;
    for(k=0; xmap_dat[k].name; k++) {
        lin=xmap_dat[k].ip<<24;
            ptr=lin>>(32-bits*2);
        x=tabx[ptr]&~(g-1);
        y=taby[ptr]&~(g-1);
        if(xmap_dat[k].name[0]=='#') {
        txt[xmap_dat[k].ip] = 0;
        for(i=1; i<g-1; i++)
            for(j=1; j<g-1; j++)
            if(((i+j)%8)==0)
                bgp(x+i, y+j, 0x202020);
        } else if(xmap_dat[k].name[0]=='$') {
        txt[xmap_dat[k].ip] = 2;
        for(i=1; i<g-1; i++)
            for(j=1; j<g-1; j++)
            if(((i-j)%8)==0)
                bgp(x+i, y+j, 0x002010);
        draw_str(x+2, y+2, g-4, g-4, xmap_dat[k].name+1, 0x005010, 1<<(bits-10), 1);
        } else
        draw_str(x+2, y+2, g-4, g-4, xmap_dat[k].name, 0x501000, 1<<(bits-10), 1);
    }
    for(i=0;i<256;i++) {
        lin=i<<24;
            ptr=lin>>(32-bits*2);
        x=tabx[ptr]&~(g-1);
        y=taby[ptr]&~(g-1);
        sprintf(name, "%d", i);
        draw_str(x+2, y+2, g-4, 11, name, txt[i]==2?0x005010:txt[i]?0x501000:0x303030, 1<<(bits-10), 0);
    }
    }
    for(i=1; i<argc; i++) {
    if(argv[i][0]=='-') {
        if(argv[i][1]=='s')
        j=1;
        if(argv[i][1]=='m')
        j=2;
    } else if(j==2) {
        fp=strchr(argv[i], '=');
        if(fp)
        fp++;
        if(sscanf(argv[i], "%d.%d.%d.%d", ip, ip+1, ip+2, ip+3)!=4) {
        fprintf(stderr, "Usage: xmap [options:-s,-m] <IP list file> <output PPM file>\n");
        fprintf(stderr, "       -m <ip>[=<name>] - draw IP mark on the map\n");
        return 1;
        }
        draw_ip(ip[0],ip[1],ip[2],ip[3], fp);
        j=0;
    } else
        j=0;
    }
    f=fopen(fout,"w");
    if(!f) {
    fprintf(stderr, "Usage: xmap [options:-s,-m] <IP list file> <output PPM file>\n");
    fprintf(stderr, "       cannot open output PPM file\n");
    return 1;
    }
    fprintf(f,"P6\n%d %d\n255\n",1<<bits,1<<bits);
    for(y=0;y<1<<bits;y++)
    for(x=0;x<1<<bits;x++) {
        c[0] = bg[x][y]>>16;
        c[1] = bg[x][y]>>8;
        c[2] = bg[x][y];
        if(c[2]>0x80) {
            fwrite(c,1,3,f);
        continue;
        }
        if(x%g == 0 || x%g == (g-1) || y%g == 0 || y%g == (g-1)) {
        c[0] = 32;
        c[1] = 16;
        if(x%(g*4) == 0 || y%(g*4) == 0 || x%(g*4) == (g*4-1) || y%(g*4) == (g*4-1))
            c[0] = 64;
        if(x%(g*8) == 0 || y%(g*8) == 0 || x%(g*8) == (g*8-1) || y%(g*8) == (g*8-1))
            c[0] = 128;
        }
        if(stat[x][y]) {
        if(stat[x][y]<4) {
            c[0]=stat[x][y]*30+30;
            c[1]=stat[x][y]*30+30;
            c[2]=stat[x][y]*50+60;
        } else {
            c[0]=c[1]=255;
            if(stat[x][y]<16)
            c[2]=stat[x][y]*16;
            else
            c[2]=255;
        }
        }
        fwrite(c,1,3,f);
    }
    fclose(f);
    return 0;
}

I have a tarball of the complete source, if anyone wants it. its author is

Stanislaw Skowronek
[email protected]