mirror of
https://github.com/MCMi460/3DS-RPC.git
synced 2025-06-19 05:55:36 -04:00
43 lines
1.9 KiB
Python
43 lines
1.9 KiB
Python
# Convert `friendCode` into `principalId`
|
|
|
|
# This method took two weeks to figure out and five minutes to code
|
|
# Thank you, https://www.3dbrew.org/wiki/Principal_ID
|
|
# for essentially making my efforts have worth
|
|
# I would kiss Meleemeister (https://www.3dbrew.org/wiki/Special:Contributions/Meleemeister)
|
|
|
|
import hashlib
|
|
|
|
class FriendCodeValidityError(Exception):
|
|
pass
|
|
|
|
class PrincipalIDValidityError(Exception):
|
|
pass
|
|
|
|
def convertFriendCodeToPrincipalId(friendCode:str) -> int:
|
|
friendCode = ''.join(filter(str.isdigit, str(friendCode)))
|
|
if len(friendCode) != 12: raise FriendCodeValidityError('an invalid friend code was passed') # Remove chances of friendCode being invalid
|
|
checksumPrincipal = str(hex(int(friendCode))) # Convert friendCode into hexadecimal
|
|
principalId = int(checksumPrincipal[4:], 16) # Remove most significant byte and convert to integer
|
|
checksumByte = hex(int(checksumPrincipal[2:][:2], 16)) # Separate checksum from checksumPrincipal
|
|
if not checkPrincipalIdValidity(checksumByte, principalId): raise FriendCodeValidityError('an invalid friend code was passed')
|
|
return principalId
|
|
|
|
def checkPrincipalIdValidity(checksumByte:int, principalId:int) -> bool:
|
|
return generateChecksumByte(principalId) == checksumByte # Check to match
|
|
|
|
def generateChecksumByte(principalId:int):
|
|
sha1 = hashlib.sha1(principalId.to_bytes(16, 'little')) # Little endian sha1 of principalId
|
|
return hex(int(sha1.hexdigest()[2:][:2], 16) >> 1) # Shift first byte to the right by one
|
|
|
|
def convertPrincipalIdtoFriendCode(principalId:int) -> str:
|
|
if not isinstance(principalId, int): raise PrincipalIDValidityError('an invalid principal id was passed')
|
|
checksumByte = generateChecksumByte(principalId)
|
|
friendCode = checksumByte + hex(principalId)
|
|
return int(friendCode.replace('0x',''), 16)
|
|
|
|
# Structure of a friendCode:
|
|
#
|
|
# (0x__ << 32) | 0x________
|
|
# Checksum PrincipalID
|
|
#
|