Search code examples
javabase64quantum-computingdwave

"base64-encoded little-endian doubles" in java


I am currently trying to use java to create requests for the DWave solvers. At the moment I am trying to wrap my head around the JSON-encoding part. Especially how the parameters of the problem are to be transmitted.

The description just reads: base64-encoded little-endian doubles (see https://docs.dwavesys.com/docs/latest/c_rest_api_5.html) which is only little info. To try and get info I tried to decode the String in the example. (The one starting with AAAAAAAA4L8AAAAAAADwPwAAAAAAAAAAAAAAAAAA+H+amZmZmZnJP....). Trying to decode it made only a IllegalArgumentException, or when shortening the String it sometimes returned some gibberish.

Does anyone have an idea how this works?

(I tried to look at the ocean-sdk source code however I'm not good enough at python to read it)


Solution

  • The example in the documentation contains multiple base64-encoded lines:

    AAAAAAAA4L8AAAAAAADwPwAAAAAAAAAAAAAAAAAA+H+amZmZmZnJPwAAAAAAAPh/AAAAAAAA+H8A
    AAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAA
    AAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAA
    AAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAA
    AAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAA
    APh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA
    +H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4
    fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/
    AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8A
    AAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAA
    AAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAA
    AAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAA
    AAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAA
    APh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA
    +H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4
    fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/
    AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8A
    AAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==
    

    The first line decodes to the following:

    $ printf 'AAAAAAAA4L8AAAAAAADwPwAAAAAAAAAAAAAAAAAA+H+amZmZmZnJPwAAAAAAAPh/AAAAAAAA+H8A' | base64 -d | xxd
    00000000: 0000 0000 0000 e0bf 0000 0000 0000 f03f  ...............?
    00000010: 0000 0000 0000 0000 0000 0000 0000 f87f  ................
    00000020: 9a99 9999 9999 c93f 0000 0000 0000 f87f  .......?........
    00000030: 0000 0000 0000 f87f 00                   .........
    

    A double comprises 8 octets, so the first double value is 0000 0000 0000 e0bf. Interpreting this as an IEEE 754 floating-point double gives you: 2.8426e-319.

    The line breaks have to be removed to give you the full base64-encoded input. I don't think the line breaks are required when serializing, but you can simply add them after you have encoded as base64 (if they are missing).

    To encode an array of doubles, you have to first convert to a byte array which can then be fed to the Base64 encoder.

    Parsing the full base64 string will give you 128 double values:

    $ printf 'AAAAAAAA4L8AAAAAAADwPwAAAAAAAAAAAAAAAAAA+H+amZmZmZnJPwAAAAAAAPh/AAAAAAAA+H8A
    AAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAA
    ....
    AAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==' | base64 -d | xxd -p -c0 | fold -w16
    000000000000e0bf
    000000000000f03f
    0000000000000000
    000000000000f87f
    9a9999999999c93f
    000000000000f87f
    000000000000f87f
    # ... value repeated ...
    000000000000f87f