Python凯撒密码暴力破解代码offset3=31时崩溃问题排查
Let's break down exactly what's going wrong in your code and fix it step by step:
1. Critical Logic Errors in option3
Your brute force function has two major flaws that cause crashes:
- The first condition
if (ord(z) - offset3 < 126)is almost always true (even negative values are less than 126). This means you’re directly using invalid values like32 - 31 = 1(a non-printable control character) and eventually negative numbers (e.g.,32 - 94 = -62), which throw aValueErrorwhen passed tochr()(sincechr()only accepts values between 0 and 1114111). - The second condition
if (ord(z) - offset3 > 126)is impossible to trigger—ord(z)maxes out at 126, so subtracting any positiveoffset3will never result in a value greater than 126. This branch never runs, so you never handle cases where the offset pushes characters below ASCII 32.
2. Similar Bug in option2
Your decryption function (option2) also has a reversed condition: if (ord(y) - offset > 126) will never be true. This means you never handle cases where subtracting the offset drops characters below ASCII 32, leading to the same crash risk for large offsets.
The Fix: Use Modulo Math for Reliable ASCII Wrapping
Instead of fragile conditional checks, we can use modulo arithmetic to guarantee all character values stay within the ASCII 32-126 range (94 total characters). Here’s the foolproof formula:
- Convert the character to a 0-93 range by subtracting 32
- Apply the offset (add for encryption, subtract for decryption)
- Use modulo 94 to wrap around the range
- Convert back to 32-126 by adding 32
Corrected Full Code
def get_menu_choice(): print('\n*** Menu ***\n') print('1. Encrypt string') print('2. Decrypt string') print('3. Brute force decryption') print('4. Quit\n') option = int(input('What would you like to do [1,2,3,4]?')) while option not in [1, 2, 3, 4]: option = int(input('Invalid choice, please enter either 1, 2, 3 or 4:')) return option def get_offset(): offset = int(input('Please enter offset value (1 to 94): ')) # Add validation to ensure valid offset range while offset < 1 or offset > 94: offset = int(input('Invalid offset! Please enter a value between 1 and 94: ')) return offset def option1(): output1 = '' encrypt = input('\nPlease enter string to encrypt: ') offset = get_offset() for x in encrypt: # Wrap character within ASCII 32-126 adjusted = (ord(x) - 32 + offset) % 94 output1 += chr(adjusted + 32) print('\nEncrypted string:\n', output1) def option2(): output2 = '' decrypt = input('\nPlease enter string to decrypt: ') offset = get_offset() for y in decrypt: # Wrap character within ASCII 32-126 adjusted = (ord(y) - 32 - offset) % 94 output2 += chr(adjusted + 32) print('\nDecrypted string:\n', output2) def option3(): brutef = input('\nPlease enter string to decrypt: ') print() for offset3 in range(0, 95): output3 = '' for z in brutef: # Same reliable wrapping for brute force adjusted = (ord(z) - 32 - offset3) % 94 output3 += chr(adjusted + 32) print(f'Offset: {offset3} = Decrypted string: {output3}') def option4(): print('\nGoodbye!') run = 'y' while run == 'y': option = get_menu_choice() if option == 1: option1() elif option == 2: option2() elif option == 3: option3() elif option == 4: option4() run = 'n'
Key Improvements:
- Replaced broken conditional checks with modulo math to keep characters within the required ASCII range
- Added offset validation to prevent invalid input
- Fixed typos (e.g.,
encrupt→encrypt) - Cleaned up code structure for better readability
- Ensured brute force resets the output string correctly for each offset
Now your brute force decryption will run without crashing for any offset from 0 to 94, and all encryption/decryption operations will reliably wrap within the specified ASCII range.
内容的提问来源于stack exchange,提问作者Brendan Harris

