# Noisy1. Intro 2. Understand the script3. Get the flag
## Intro![](https://imgur.com/Dwk2KCD.png)
28800 lines with random floats.
*Nice*
## Understanding the script
```pythonimport numpy as npfrom random import gaussmorse = REDACTEDrepeats = REDACTEDpointed = []for c in morse:    if c == ".":        pointed.extend([1 for x in range(10)])    if c == "-":        pointed.extend([1 for x in range(20)])    if c == " ":        pointed.extend([0 for x in range(20)])    pointed.extend([0 for x in range(10)]) with open("points.txt", "w") as f:    for _ in range(repeats):        signal = pointed        output = []        for x, bit in enumerate(signal):            output.append(bit + gauss(0,2))         signal = list(np.array(output) - .5)        f.write('\n'.join([str(x) for x in signal])+"\n")f.close()```
There is 2 things we don't know here : morse, which is the flag, and repeats, the number of times the flag is repeated.
The first ```for``` is used to translate the morse code into 0 and 1.We can see after each character, ten 0 are printed. 
For example, ```".-"``` -> 11111111110000000000111111111111111111110000000000
The entire message is stored in ```pointed```.
```with open("points.txt", "w") as f: ```open the file to write the message inside, with a ```for``` loop to repeat the message [repeats] times.
```pythonfor x, bit in enumerate(signal):            output.append(bit + gauss(0,2))         signal = list(np.array(output) - .5)				f.write('\n'.join([str(x) for x in signal])+"\n")```
This block of code a every bit of pointed in the file, adding to it ```gauss(0, 2)```.
Gauss is a function which return a random number chosen like this :
![](https://imgur.com/9VqacO7.png)
with here μ = 0 and σ = 2
Finally, we can see here ```signal = list(np.array(output) - .5)``` that we substract 0.5 to this number. 
I don't really know the reason, except to make me lose 30min...  :cry:
### Recap :
- As the message is random-based, we need to do an average to get the real character, this is why there is 10 character each time and why we repeat the message- We have to find either the length of the message or the number of repetition.
## Get the flagFirst we have to find the possible sizes for the flag. It can be easily done with this python script :```possibleSize = []a = 0for i in range(1, 2880)):    if 2880%i == 0:        a += 1        possibleSize.append(i)print(possibleSize)```
For every int between 1 and 2880 (2880 = 28800/10, because every character in the message is repeated 10 times), we will see if 2880 mod i (were i is a possible message length) is equal to 0, because there is only entire message repetion. We have repeats\*messageLength = 2880.
The result is ```[1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 30, 32, 36, 40, 45, 48, 60, 64, 72, 80, 90, 96, 120, 144, 160, 180, 192, 240, 288, 320, 360, 480, 576, 720, 960, 1440]```
I don't think the message is less than 10 morse character long, so let's remove some values : 
```pythonpossibleSize = [15, 16, 18, 20, 24, 30, 32, 36, 40, 45, 48, 60, 64, 72, 80, 90, 96, 120, 144, 160, 180, 192, 240, 288, 320, 360, 480, 576, 720, 960, 1440]```
Now we have everything we need to write the solver script
```pythonpossibleSize = [15, 16, 18, 20, 24, 30, 32, 36, 40, 45, 48, 60, 64, 72, 80, 90, 96, 120, 144, 160, 180, 192, 240, 288, 320, 360, 480, 576, 720, 960, 1440]filename = r"F:\CTF\angstromCTF\misc\Noisy\4ea.txt"```
and we read the file 
``` pythonwith open(filename) as f:    content = f.readlines()content = [float(x.strip())+0.5 for x in content]  #don't forget to add 0.5 to the value read```content contain every lines of the file in an array. Let's sum every group of ten values :```pythonten = 10tenAdded = 0allAddedG10 = []for i in range(2880):    tenAdded = 0    for j in range(ten):        tenAdded += content[i*ten+j] #we add the values of the nth group of ten    allAddedG10.append(tenAdded)```
allAddedG10 now contain every group of ten.
NOW LET'S HAVE FUN
Now everything will be inside a for loop, to test every possible sizes :```pythonfor size in possibleSize:```
And, before anything else, I need to show your how I will process the dataLet's take an example :```allAddedG10 = [12, 15, 3, 9, 16, 5, 10, 8, 10, 9, 9, -4] #len(allAddedG10) = 12possibleSizes = [1, 2, 3, 4, 6, 12] #every divisor of 12```
![](https://imgur.com/Delh86K.png)
Depending on the size, we put the set in defferent array. With a size of 4, there is 4 column, etc...
Then, we can do the average ? of the column. If this average is greater than 5, the character of the message is a 1, else, it's a 0.
And we just have to check every array, to se if the output is valid :
![](https://imgur.com/yAxtBvk.png)
We find a valid output with size = 3, and the output is "-"
Let's do the same on the challenge.
```python    nbRepeat = int((len(allAddedG10))/size) #because repeats*messageLength = len(allAddedG10)  <=> repeats = len(allAddedG10) / messageLength      arrayPart = []    arrayG10 = []     for i in range(nbRepeat):         arrayPart = []        for j in range(size):            arrayPart.append(allAddedG10[i*size+j])        arrayG10.append(arrayPart)```
We now have an array with every groups of 10, and do the average of the columns will give us the character of the message, if we use the right size.
Let's calculate the total of every column :```python    columnTotal = [0 for x in range(size)]     for i in range(nbRepeat): #i stand for the number of the row         for j in range(size): #j stand for the number of the column            columnTotal[j] += arrayG10[i][j] ```
![](https://imgur.com/OfYF4kG.png)
Now, in columnTotal, we have the total of each column.
Calculation of the average and the final value: 
```python		definitivValues = []		for i in range(size):			average = columnTotal[i]/(nbRepeat*ten)			if average < 0.5:					average = 0			else:					average = 1			definitivValues.append(average)```
Now we want to avoid every incoherent values, for example those which don't start with a 1 and end with a 0 :
```python		if definitivValues[0] == 1 and definitivValues[-1] == 0:			print(size)			print(definitivValues)```
Final script : ```pythonpossibleSize = [15, 16, 18, 20, 24, 30, 32, 36, 40, 45, 48, 60, 64, 72, 80, 90, 96, 120, 144, 160, 180, 192, 240, 288, 320, 360, 480, 576, 720, 960, 1440]filename = r"F:\CTF\angstromCTF\misc\Noisy\4ea.txt"
with open(filename) as f:    content = f.readlines()content = [float(x.strip())+0.5 for x in content]  #don't forget to add 0.5 to the value read
ten = 10tenAdded = 0allAddedG10 = []for i in range(2880):    tenAdded = 0    for j in range(ten):        tenAdded += content[i*ten+j] #we add the values of the nth group of ten    allAddedG10.append(tenAdded)
for size in possibleSize:	print("------------------------------")	nbRepeat = int((len(allAddedG10))/size) #because repeats\*messageLength = len(allAddedG10)  <=> repeats = len(allAddedG10) / messageLength 
	arrayPart = []	arrayG10 = []
	for i in range(nbRepeat): 			arrayPart = []			for j in range(size):					arrayPart.append(allAddedG10[i*size+j])			arrayG10.append(arrayPart)	columnTotal = [0 for x in range(size)] 	for i in range(nbRepeat): #i stand for the number of the row
		for j in range(size): #j stand for the number of the column				columnTotal[j] += arrayG10[i][j] 	definitivValues = []	for i in range(size):		average = columnTotal[i]/(nbRepeat*ten)		if average < 0.5:				average = 0		else:				average = 1		definitivValues.append(average)	if definitivValues[0] == 1 and definitivValues[-1] == 0:		print(size)		print(definitivValues)```
We can see that 16, 24, 72, 90, 96,... are valid values
Now forget every values with incoherent values, like three 0, three 1, more than four 0, etc...
The first value working is for size = 96 : `.- -. --- .. ... -.-- -. --- .. ... .`
Translated, it gives us : `ANOISYNOISE`
`Flag : ANOISYNOISE`
-----
*If you have any questions, you can dm me on Discord, nhy47paulo#3590*