pythonprotocol-buffers

blackboxprotobuf showing positive values instead of negative values for protobuf response


I have an issue where blackboxprotobuf takes response of protobuf & returning the dictionary where i see few values where suppose to be negative instead coming as positive value.

Calling an APi with lat (40.741895) & long(-73.989308). Using these lat & long, a key is genereated '81859706' that be used in the api.

For Key Generation we are using paid framework.

url = "https://gspe85-ssl.ls.apple.com/wifi_request_tile"

response =requests.get(url, headers={
    'Accept': '*/*', 
    'Connection': 'keep-alive',
    'X-tilekey': "81859706",
    'User-Agent': 'geod/1 CFNetwork/1496.0.7 Darwin/23.5.0',
    'Accept-Language': 'en-US,en-GB;q=0.9,en;q=0.8',
    'X-os-version': '17.5.21F79'
    })

Which returns protobuf as response. For the same using blackboxprotobuf to convert protobuf_to_json

snippet

message, typedef = blackboxprotobuf.protobuf_to_json(response.content)
json1_data = json.loads(message)

Response:

        "2": [
            {
                "4": {
                    "2": {
                        "1": 1,
                        "2": 1
                    }
                },
                "5": 124103876854927,
                "6": {
                    "1": 407295068,
                    "2": 3555038608 //This values should be negative
                }
            },

Any help how to debug this response & fix this issue.

Thank you


Solution

  • The bit value that comes for the number is

    >>> bin(3555038608)
    '0b11010011111001011001010110010000'
    

    If you take 2s complement of that number, you will get the negative that you want.

    >>> def twos_comp(val, bits):
    ...     """compute the 2's complement of int value val"""
    ...     if (val & (1 << (bits - 1))) != 0: # if sign bit is set e.g., 8bit: 128-255
    ...         val = val - (1 << bits)        # compute negative value
    ...     return val                         # return positive value as is
    ...
    >>> twos_comp(3555038608, 32)
    -739928688
    

    If you know the bit length of coordinates, in this case 32. Since its an int. You can convert it back, using this.