amoreno
amoreno

Reputation: 83

Integer encoding format

I've run across some PIN encoding which I'm trying to figure out so I can improve upon a web application used at my place of work.

When I reset users' PINs (in this case, just my own for testing purposes), I'm seeing the following:

PIN      VALUE
000000 = 7F55858585858585
111111 = 7F55868686868686
222222 = 7F55878787878787
999999 = 7F558E8E8E8E8E8E

000001 = 7F01313131313132
000011 = 7F55858585858686
000111 = 7F01313131323232
001111 = 7F55858586868686
011111 = 7F01313232323232
000002 = 7F02323232323234
100000 = 7F01323131313131
111112 = 7F03343434343435

123456 = 7F0738393A3B3C3D
654321 = 7F073D3C3B3A3938

1357924680 = 7F01323436383A3335373931

1111111111 = 7F5586868686868686868686
1234567890 = 7F0132333435363738393A31

It's clearly just hex, and always starts with 7F (1111111 or 127), but I'm not seeing a pattern for how the next two characters are chosen. Those two characters seem to be the determining value for converting the PIN.

For example:

000000       = 7F 55 858585858585
7F (hex)     = 127 (dec) or 1111111 (bin) ## appears to not be used in the calculation?
55 (hex)     =  85 (dec) or 1010101 (bin) 
0 (PIN) + 85 =  85
000000       =  858585858585

111111       = 7F 55 868686868686
7F (hex)     = 127 (dec) or 1111111 (bin) ## appears to not be used in the calculation?
55 (hex)     =  85 (dec)
1 (PIN) + 85 =  86
111111       =  868686868686

But then also:

1357924680   = 7F 01 323436383A3335373931
01 (hex)     = 31 (dec) ?
1 (PIN) + 31 = 32
1357924680   = 323436383A3335373931

Any help pointing me in the right direction would be greatly appreciated.

Upvotes: 0

Views: 77

Answers (1)

JosefZ
JosefZ

Reputation: 30103

I don't see enough data in your minimal reproducible example to uncover an algorithm how the pinshift value should be determined (supplied to the pin_to_hex function). A random value is used in the following solution:

def hex_to_pin( pinhex: str) -> list:
    '''
    decode a PIN from a particular hexadecimal-formatted string
    hex_to_pin('7F0738393A3B3C3D')
    
    inverse of the "pin_to_hex" function (any of the following):
    hex_to_pin(pin_to_hex('123456', 7))
    pin_to_hex(*hex_to_pin('7F0738393A3B3C3D'))
    '''
    xxaux = bytes.fromhex(pinhex)
    return [bytes([x - xxaux[1] for x in xxaux[2:]]).decode(),
            xxaux[1]]


def pin_to_hex( pindec: str, pinshift: int, upper=False) -> str:
    '''
    encode a PIN to a particular hexadecimal-formatted string
    pin_to_hex('123456', 7)
    
    inverse of the "hex_to_pin" function (any of the following):
    pin_to_hex(*hex_to_pin('7F0738393A3B3C3D'),True)
    hex_to_pin(pin_to_hex('123456', 7))
    '''
    shift_ = max( 1, pinshift % 199) ## 134 for alpha-numeric PIN code
    retaux = [b'\x7F', shift_.to_bytes(1, byteorder='big')]
    for digit_ in pindec.encode():
        retaux.append( (digit_ + shift_).to_bytes(1, byteorder='big'))
    if upper:
        return (b''.join(retaux)).hex().upper()
    else:
        return (b''.join(retaux)).hex()


def get_pin_shift( pindec: str) -> int:
    '''
    determine "pinshift" parameter for the "pin_to_hex" function
    currently returns a random number
    '''
    return random.randint(1,198)  ## (1,133) for alpha-numeric PIN code
    

hexes = [
        '7F01323436383A3335373931',
        '7F0738393A3B3C3D',
        '7F558E8E8E8E8E8E'
        ]
print("hex_to_pin:")
maxlen = len( max(hexes, key=len))
deces = []
for xshex in hexes:
    xsdec = hex_to_pin( xshex)
    print( f"{xshex:<{maxlen}} ({xsdec[1]:>3}) {xsdec[0]}")
    deces.append(xsdec[0])

import random
print("pin_to_hex:")
for xsdec in deces:
    xsshift = get_pin_shift( xsdec)
    xshex = pin_to_hex( xsdec, xsshift)
    print( f"{xshex:<{maxlen}} ({xsshift:>3}) {xsdec}")

Output SO\71875753.py

hex_to_pin:
7F01323436383A3335373931 (  1) 1357924680
7F0738393A3B3C3D         (  7) 123456
7F558E8E8E8E8E8E         ( 85) 999999
pin_to_hex:
7f1041434547494244464840 ( 16) 1357924680
7f4e7f8081828384         ( 78) 123456
7f013a3a3a3a3a3a         (  1) 999999

Upvotes: 1

Related Questions