Zerocode

From Second Life Wiki
Revision as of 17:17, 10 September 2024 by Wulfie Reanimator (talk | contribs) (Added sections and full alternative in Python 3.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Python 3

This code is a modern implementation of the earlier Python 2 code below.

def encode(input: bytes) -> bytes:
    """
    Zero-bytes are run-length encoded so that up to 255 zeroes become `\\x00\\xff`
    """
    out = bytearray()
    i, n = 0, len(input)
    while i < n: # While-loop for index skipping.
        if (zeroes := (input[i] == 0x00)):
            while (i + zeroes < n) and input[i + zeroes] == 0x00: zeroes += 1
            out.extend([0x00, zeroes])
            i += zeroes
        else:
            out.append(input[i])
            i += 1
    return bytes(out)

def decode(input: bytes) -> bytes:
    """
    Converts bytes where zeroes are run-length encoded,
    such that `\\x00\\xff` is unpacked into 255 `\\x00` bytes.
    """
    out = bytearray()
    i, n = 0, len(input)
    while i < n: # While-loop for index skipping.
        if input[i] == 0x00:
            out.extend(b'\0' * input[i + 1])
            i += 2 # Assumes input was valid.
        else:
            out.append(input[i])
            i += 1
    return bytes(out)

def hex2byte(input: str) -> bytes:
    """
    Converts formatted string `'AA BB CC DD'` into bytes. Spaces are ignored.
    """
    return bytes.fromhex(input.replace(' ',''))

def byte2hex(input: bytes) -> str:
    """
    Converts bytes into formatted string `'AA BB CC DD'`.
    """
    return ' '.join(f'{byte:02X}' for byte in input)

Python 2

Zero-encoding and decoding functions and a couple of useful functions from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/510399

This code is used in the Presence Code example.

# From http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/510399
# From http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/510399
def ByteToHex( byteStr ):
    """
    Convert a byte string to it's hex string representation e.g. for output.
    """
    
    # Uses list comprehension which is a fractionally faster implementation than
    # the alternative, more readable, implementation below
    #   
    #    hex = []
    #    for aChar in byteStr:
    #        hex.append( "%02X " % ord( aChar ) )
    #
    #    return ''.join( hex ).strip()        

    return ''.join( [ "%02X " % ord( x ) for x in byteStr ] ).strip()


def HexToByte( hexStr ):
    """
    Convert a string hex byte values into a byte string. The Hex Byte values may
    or may not be space separated.
    """
    # The list comprehension implementation is fractionally slower in this case    
    #
    #    hexStr = ''.join( hexStr.split(" ") )
    #    return ''.join( ["%c" % chr( int ( hexStr[i:i+2],16 ) ) \
    #                                   for i in range(0, len( hexStr ), 2) ] )
 
    bytes = []

    hexStr = ''.join( hexStr.split(" ") )

    for i in range(0, len(hexStr), 2):
        bytes.append( chr( int (hexStr[i:i+2], 16 ) ) )

    return ''.join( bytes )


def zero_encode(inputbuf):
    newstring =""
    zero = False
    zero_count = 0            
    for c in inputbuf:
        if c != '\0':
            if zero_count != 0:
                newstring = newstring + chr(zero_count)
                zero_count = 0
                zero = False

            newstring = newstring + c
            
        else:
            if zero == False:
                newstring = newstring + c
                zero = True
                
            zero_count = zero_count + 1
    if zero_count != 0:
        newstring = newstring + chr(zero_count)


    return newstring

def zero_decode(inputbuf):
    newstring =""
    in_zero = False
    for c in inputbuf:
        if c != '\0':
            if in_zero == True:
                zero_count = ord(c)
                zero_count = zero_count -1
                while zero_count>0:

                    newstring = newstring + '\0'
                    zero_count = zero_count -1
                in_zero = False
            else:
                newstring = newstring + c
        else:
            newstring = newstring + c
            in_zero = True
    return newstring

def zero_decode_ID(inputbuf):
    newstring =""
    in_zero = False
    #print "in encode, input is", ByteToHex(inputbuf)
    for c in inputbuf:
        if c != '\0':
            if in_zero == True:
                zero_count = ord(c)
                zero_count = zero_count -1
                while zero_count>0:

                    newstring = newstring + '\0'
                    zero_count = zero_count -1
                in_zero = False
            else:
                newstring = newstring + c
        else:
            newstring = newstring + c
            in_zero = True
    return newstring[:4]