L’énnoncé nous donne les instructions, nous sommes sages, nous les suivons :
import numpy as np
import numpy.fft
data = np.fromfile("fftea", dtype=numpy.complex64)
# Compute FFT
fft = np.fft.fft(data, n=64)
print(fft)
Le résultat est un vecteur de complexes dont ont voit que les parties imaginaires sont nulles et les parties réelles des premières valeurs ressemblent fortement au codage ASCII de ‘FCSC’ :
[ 69.99999988+0.j 67.00000015+0.j 82.99999948+0.j 67.00000005+0.j
122.99999918+0.j 53.0000006 +0.j 97.9999997 +0.j 57.00000068+0.j
54.00000046+0.j 57.00000025+0.j 48.99999935+0.j 48.99999908+0.j
50.99999927+0.j 53.99999893+0.j 54. +0.j 56.00000025+0.j
100.00000099+0.j 55.00000014+0.j 101.9999995 +0.j 99.00000019+0.j
50.00000014+0.j 55.99999962+0.j 102.00000109+0.j 100.99999964+0.j
49.00000029+0.j 97.00000069+0.j 55.00000121+0.j 99.9999997 +0.j
47.99999969+0.j 54.99999909+0.j 48.99999946+0.j 55.99999973+0.j
50.99999936+0.j 101.00000063+0.j 101.00000067+0.j 97.00000093+0.j
52.00000081+0.j 99.99999898+0.j 100.99999995+0.j 52.99999991+0.j
52.00000049+0.j 53.00000068+0.j 56.00000003+0.j 100.00000032+0.j
99.99999925+0.j 49.00000111+0.j 47.99999983+0.j 49.9999999 +0.j
54.99999882+0.j 99.99999967+0.j 54.00000006+0.j 102.00000044+0.j
50.00000082+0.j 57.00000036+0.j 98.99999977+0.j 50.00000009+0.j
51.99999971+0.j 50.99999939+0.j 52.9999997 +0.j 47.99999872+0.j
97.00000085+0.j 48.9999997 +0.j 48.0000002 +0.j 125.00000034+0.j]
Les pages man sont très utiles :
$ man ascii
ascii(7) Miscellaneous Information Manual ascii(7)
NAME
ascii - ASCII character set encoded in octal, decimal, and hexadecimal
DESCRIPTION
ASCII is the American Standard Code for Information Interchange. It is a 7-bit code. Many 8-bit codes (e.g.,
ISO/IEC 8859-1) contain ASCII as their lower half. The international counterpart of ASCII is known as ISO/IEC 646-IRV.
The following table contains the 128 ASCII characters.
C program '\X' escapes are noted.
Oct Dec Hex Char Oct Dec Hex Char
────────────────────────────────────────────────────────────────────────
000 0 00 NUL '\0' (null character) 100 64 40 @
001 1 01 SOH (start of heading) 101 65 41 A
002 2 02 STX (start of text) 102 66 42 B
003 3 03 ETX (end of text) 103 67 43 C
004 4 04 EOT (end of transmission) 104 68 44 D
005 5 05 ENQ (enquiry) 105 69 45 E
006 6 06 ACK (acknowledge) 106 70 46 F
007 7 07 BEL '\a' (bell) 107 71 47 G
010 8 08 BS '\b' (backspace) 110 72 48 H
011 9 09 HT '\t' (horizontal tab) 111 73 49 I
012 10 0A LF '\n' (new line) 112 74 4A J
013 11 0B VT '\v' (vertical tab) 113 75 4B K
014 12 0C FF '\f' (form feed) 114 76 4C L
015 13 0D CR '\r' (carriage ret) 115 77 4D M
016 14 0E SO (shift out) 116 78 4E N
017 15 0F SI (shift in) 117 79 4F O
020 16 10 DLE (data link escape) 120 80 50 P
021 17 11 DC1 (device control 1) 121 81 51 Q
022 18 12 DC2 (device control 2) 122 82 52 R
023 19 13 DC3 (device control 3) 123 83 53 S
...
On modifie le script python pour se construire une chaine de caractères en prenant soin d’arrondir la conversion en entier proprement :
import numpy as np
import numpy.fft
data = np.fromfile("fftea", dtype=numpy.complex64)
# Compute FFT
fft = np.fft.fft(data, n=64)
str = ''
for c in fft:
str += chr(int(c.real + 0.5))
print(str)
On exécute le script:
$ python3 flag.py
FCSC{5b969113668d7fc28fe1a7d07183eea4de5458dd1027d6f29c24350a10}
Tada.