0

I'm trying to calculate NodeId's according that are compliant with BEP42

I'm not clever enough to understand the example code given in BEP42 However the algorithm for creating nodeId's is given as : crc32c((ip & 0x030f3fff) | (r << 29))

There is also a table of results, from which we can see that a good nodeID for the ip address 21.75.31.124 would start with 5a3ce9, if the random seed used was '86' (in decimal I'm supposing).

So I try the following :

InetSocketAddress a = new InetSocketAddress("21.75.31.124",6881);
byte[] ba = a.getAddress().getAddress();
int ia = ByteBuffer.wrap(ba).order(ByteOrder.BIG_ENDIAN).getInt();
int r = 86;
int calc = (ia & 0x030f3fff) | (r<<29);
Crc32C crc = new Crc32C();
crc.update(calc);
int foo = crc.getIntValue();
byte[] ret = ByteBuffer.allocate(4).putInt(foo).array();
String retStr = Hex.encodeHexString(ret);
System.out.println("should be : 5a3ce9 is " + retStr);

But I get 6ea6c88c, which is wrong in just about every way. the 8472 has some code used to decide if a client's nodeId is BEP42 compliant, but I don't understand that code either.

Could anyone tell me what is wrong with the code above?

Richard
  • 1,070
  • 9
  • 22
  • The BEP42 spec. is a bit unclear. `r` and `rand` is not the same. It's `r = rand & 0x7` – Encombe Oct 01 '18 at 12:29
  • Yeah.. it's not the best document I've ever read. At the moment, I have it calculating the node prefix correctly, except for the last hex digit, which is sometimes wrong and sometimes right.. I think it has to do with this 'only take the first 21 bits' requirement... which I don't understand. – Richard Oct 01 '18 at 12:43
  • The key is to read and fully understand the example code. – Encombe Oct 01 '18 at 12:45
  • Well yes, but there's no doubt the document is opaque, almost deliberately opaque. And the actual method of encoding the IP address is bizarrely esoteric. I'm almost tempted to not implement it at all out of protest. Even the MLDHT boostrap servers aren't enforcing it anyway. – Richard Oct 01 '18 at 13:16

1 Answers1

0

All, please ignore, answer is :

    InetSocketAddress a = new InetSocketAddress("21.75.31.124",6881);
    byte[] ip = a.getAddress().getAddress();
    int r = 86;

    byte[] mask = { 0x03, 0x0f, 0x3f, (byte) 0xff };   
    for(int i=0;i<mask.length;i++) {
        ip[i] &= mask[i];
    }
    ip[0] |= r << 5;
    Crc32C c = new Crc32C();
    c.update(ip, 0, Math.min(ip.length, 8));
    int crcVal = (int)c.getValue();
    String s = Integer.toHexString(crcVal);             

    System.out.println("should be : 5a3ce9 is " + s);
Richard
  • 1,070
  • 9
  • 22