Python破解挑战算法解析求助:已知位运算与取模求Flag推导逻辑
Hey there! Let's break down this code step by step so you can understand how to reverse-engineer the flag from the given SOLUCE array. I'll start with the forward execution flow, then walk through the exact method to derive each character of the flag.
First, let's clean up and present the full code snippet you provided (filling in the incomplete condition):
PASS = input('Enter the Flag: ') KEY = 'I know, you love decrypting Byte Code !' I = 5 SOLUCE = [57, 73, 79, 16, 18, 26, 74, 50, 13, 38, 13, 79, 86, 86, 87] KEYOUT = [] for X in PASS: KEYOUT.append((ord(X) + I ^ ord(KEY[I])) % 255) I = (I + 1) % len(KEY) if SOLUCE == KEYOUT: print("Correct!") else: print("Wrong!")
1. Forward Execution: How the Code Transforms the Flag
Let's walk through what happens when you input a valid flag:
- Initial Setup:
PASSis your input flag (the value we need to find).KEYis a fixed string used for transformation.Istarts at 5 — this is the index we use to pick characters fromKEYas we iterate through the flag.SOLUCEis the target array that our transformed flag (KEYOUT) must match.
- Loop Through Each Flag Character:
For every characterXinPASS:- Convert
Xto its ASCII value withord(X). - Add the current value of
Ito this ASCII number (note: addition has higher precedence than XOR in Python, so this happens first). - XOR the result with the ASCII value of
KEY[I](the character fromKEYat indexI). - Take modulo 255 to keep the value in the 0-254 range (though for our case, this step doesn't actually change anything — more on that later).
- Append this final value to
KEYOUT. - Update
I: increment it by 1, then take modulo the length ofKEYto wrap around if we reach the end of theKEYstring.
- Convert
- Validation:
The code checks ifKEYOUTmatchesSOLUCE— if yes, the input flag is correct.
2. Reverse-Engineering: Deriving the Flag
Since we have the final SOLUCE array, we can reverse each transformation step to get back the original flag characters. Here's the step-by-step method:
Step 1: Map out the sequence of I values
We know I starts at 5 and increments by 1 each loop iteration. Since SOLUCE has 15 elements, we need 15 I values. The length of KEY is 39, so we don't hit any wrapping (all I values stay below 39). The sequence is:5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
Step 2: Get the corresponding KEY character ASCII values
For each I in the sequence above, get K_n = ord(KEY[I]) (the ASCII value of the KEY character at that index). For example:
I=5→KEY[5]is'w'→K_n=119I=6→KEY[6]is','→K_n=44- And so on for all 15 indices.
Step 3: Reverse the mathematical operations
The forward transformation (simplified, since mod 255 doesn't affect our values) is:SOLUCE[n] = (ord(X_n) + I_n) ^ K_n
Where:
X_n= nth character of the flagI_n= nth value in ourIsequenceK_n= nthKEYASCII value
Since XOR is its own inverse (if a ^ b = c, then a = c ^ b), we can rearrange this to solve for ord(X_n):
- First, reverse the XOR:
(ord(X_n) + I_n) = SOLUCE[n] ^ K_n - Then subtract
I_nto get the ASCII value of the flag character:ord(X_n) = (SOLUCE[n] ^ K_n) - I_n - Convert the ASCII value back to a character with
chr(ord(X_n))
Step 4: Apply to every element in SOLUCE
Repeat the above calculation for each of the 15 elements in SOLUCE to get each character of the flag in order.
Example: First Flag Character
Let's compute the first one to make it concrete:
SOLUCE[0] = 57,I_n=5,K_n=119(fromKEY[5]='w')- Compute
57 ^ 119: binary00111001 ^ 01110111 = 01001110→ decimal78 - Subtract
I_n:78 -5 =73 chr(73)is'I'— that's the first character of the flag.
Repeat this process for all 15 elements, and you'll have the full flag.
内容的提问来源于stack exchange,提问作者mahmoudadel

