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]