如何在Python中使用UUID模块生成无符号整数及不同位数的有符号整数
Great question! Since you already know how to get a 64-bit unsigned integer from uuid1(), extending this to signed integers of different bit lengths is just a matter of handling the sign bit correctly. Let's break this down for each bit length you asked about.
First, a quick refresher: uuid1().int gives us a 128-bit unsigned integer. Signed integers use their highest bit as a sign flag (1 = negative, 0 = positive). For an N-bit signed integer, values range from -2^(N-1) to 2^(N-1)-1. To convert an unsigned snippet of the UUID to signed, we check if the value is above the midpoint (2^(N-1)); if so, subtract 2^N to get the negative equivalent.
8-bit Signed Integer
We'll grab the lowest 8 bits of the UUID, then adjust for the sign bit:
from uuid import uuid1 def get_signed_8bit(): # Get lowest 8 bits as unsigned integer unsigned = uuid1().int & 0xFF # Convert to signed: if >= 128 (0x80), subtract 256 (0x100) return unsigned if unsigned < 0x80 else unsigned - 0x100 # Example usage print(get_signed_8bit()) # Outputs between -128 and 127
Or a shorter approach using ctypes (it handles sign conversion automatically):
import ctypes from uuid import uuid1 def get_signed_8bit(): return ctypes.c_int8(uuid1().int & 0xFF).value
16-bit Signed Integer
Same logic, but targeting 16 bits:
from uuid import uuid1 def get_signed_16bit(): unsigned = uuid1().int & 0xFFFF return unsigned if unsigned < 0x8000 else unsigned - 0x10000 # Example output: between -32768 and 32767 print(get_signed_16bit())
ctypes alternative:
import ctypes from uuid import uuid1 def get_signed_16bit(): return ctypes.c_int16(uuid1().int & 0xFFFF).value
32-bit Signed Integer
Extend to 32 bits:
from uuid import uuid1 def get_signed_32bit(): unsigned = uuid1().int & 0xFFFFFFFF return unsigned if unsigned < 0x80000000 else unsigned - 0x100000000 # Outputs between -2147483648 and 2147483647 print(get_signed_32bit())
ctypes shortcut:
import ctypes from uuid import uuid1 def get_signed_32bit(): return ctypes.c_int32(uuid1().int & 0xFFFFFFFF).value
64-bit Signed Integer
You already know how to get the unsigned high 64 bits with uuid1().int >> 64. For signed, we can either convert that high 64-bit value, or use the low 64 bits—both work:
Option 1: Convert the high 64 bits (matching your original approach)
from uuid import uuid1 def get_signed_64bit_high(): unsigned_high = uuid1().int >> 64 return unsigned_high if unsigned_high < 0x8000000000000000 else unsigned_high - 0x10000000000000000 # Outputs between -9223372036854775808 and 9223372036854775807 print(get_signed_64bit_high())
Option 2: Use the low 64 bits
from uuid import uuid1 def get_signed_64bit_low(): unsigned_low = uuid1().int & 0xFFFFFFFFFFFFFFFF return unsigned_low if unsigned_low < 0x8000000000000000 else unsigned_low - 0x10000000000000000 print(get_signed_64bit_low())
ctypes alternative for either:
import ctypes from uuid import uuid1 def get_signed_64bit_high(): return ctypes.c_int64(uuid1().int >> 64).value def get_signed_64bit_low(): return ctypes.c_int64(uuid1().int & 0xFFFFFFFFFFFFFFFF).value
128-bit Signed Integer
Since uuid1().int is already 128 bits unsigned, we just need to adjust for the sign bit (the very first bit of the UUID):
from uuid import uuid1 def get_signed_128bit(): unsigned_128 = uuid1().int # 2^127 is the midpoint for 128-bit signed integers midpoint = 0x80000000000000000000000000000000 return unsigned_128 if unsigned_128 < midpoint else unsigned_128 - (midpoint * 2) # Outputs between -170141183460469231731687303715884105728 and 170141183460469231731687303715884105727 print(get_signed_128bit())
Note: Python doesn't have a built-in 128-bit integer type in ctypes (on most systems), so the manual adjustment is the way to go here.
内容的提问来源于stack exchange,提问作者Chukwujiobi Canon

