Python中AES加密addRoundKey函数出现str与int异或错误求助
Hey there! Let's tackle that TypeError: unsupported operand type(s) for ^=: 'str' and 'int' error you're hitting. The root cause is exactly what you suspected: your state array is holding string characters from the input message, while your round key contains integers—you can't XOR those two types directly. Here's how to fix it step by step:
1. Fix State Initialization
First, your current import of state from numpy.random._examples.cffi.extending is not appropriate for AES state storage. Instead, create a dedicated state array in your encrypt function. We'll use a list of integers (or a numpy array if you prefer) to hold the numeric representation of your message.
2. Convert String Message to Integer (ASCII) Values
AES operates on bytes (integers between 0-255), so you need to convert each character in your input string to its corresponding ASCII value. Also, AES requires a 16-byte (16-character) input block—if your message is shorter, you'll need to pad it (we'll use simple padding here; for production, use a standard like PKCS#7).
3. Update the Encrypt Function
Modify the encrypt function to handle the string-to-integer conversion, proper state initialization, and padding.
Modified Code Example
def keyExpansionCore(x, i): # Implement your key expansion core logic here later pass def subBytes(state): # Implement your SubBytes logic here later pass def shiftRows(state): # Implement your ShiftRows logic here later pass def mixColumns(state): # Implement your MixColumns logic here later pass def addRoundKey(state, roundKey): for i in range(16): state[i] ^= roundKey[i] def encrypt(message, key): # Initialize state as a list of integers (16 elements for AES-128) state = [0] * 16 # Convert message string to ASCII integers, pad if needed message_bytes = [ord(c) for c in message] # Pad with spaces if message is shorter than 16 characters while len(message_bytes) < 16: message_bytes.append(ord(' ')) # Truncate if longer than 16 (split into blocks for real-world use) message_bytes = message_bytes[:16] # Populate state with converted message bytes for i in range(16): state[i] = message_bytes[i] numberOfRounds = 10 # AES-128 uses 10 rounds, adjust for other variants # keyExpansion() # Uncomment once you implement the key expansion function addRoundKey(state, key) for round in range(numberOfRounds - 1): subBytes(state) shiftRows(state) mixColumns(state) addRoundKey(state, key) # Final round (no mixColumns step) subBytes(state) shiftRows(state) addRoundKey(state, key) # Optional: Convert encrypted state back to string for readability encrypted_message = ''.join([chr(byte) for byte in state]) print("Encrypted message:", encrypted_message) def main(): message = input("Enter a message: ") # Key should be 16 integers (0-255) for AES-128 key = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] encrypt(message, key) if __name__ == "__main__": main()
Key Changes Explained
- State Initialization: We create
state = [0] * 16to ensure it's a list of integers, ditching the incorrect numpy import. - String to Integer Conversion:
[ord(c) for c in message]turns each character into its ASCII integer value (e.g., 'A' becomes 65). - Padding: We pad shorter messages with spaces to meet AES's 16-byte block requirement. For production, use PKCS#7 padding (add bytes equal to the number of padding bytes needed).
- Round Count: AES-128 uses 10 rounds, so we adjusted
numberOfRoundsfrom 1 to 10 (your original code had only 1 round, which isn't secure).
Once you implement the remaining AES functions (keyExpansion, subBytes, etc.), this code should run without the type error. Let me know if you need help with those parts!
内容的提问来源于stack exchange,提问作者salim

