Tags: crypto cry rev mj0ln1r base26 invaders
Rating:
The challenge has a java file name `numericalEncoder.java`
```java
//Encoding program originally by Logan DesRochers
import java.lang.Math;
import java.util.ArrayList;
import java.util.Scanner;
public class numericalEncoder{
public static void main(String[] args){
String alphabet = "abcdefghijklmnopqrstuvwxyz";
Scanner sc = new Scanner(System.in);
System.out.println("Enter string to be encoded: ");
String m = sc.nextLine();
m = m.toLowerCase();
System.out.println("Enter int block size: ");
int r = sc.nextInt();
//padding to variable block size
if(m.length() % r != 0){
while(m.length() % r != 0){
m = m + "x";
}
}
System.out.println("M after padding: " + m);
//Variable block size
ArrayList<Integer> encodedBlocks = new ArrayList<Integer>();
int numBlocks = m.length() / r;
for(int i = 0; i < numBlocks; i++){
String block = m.substring(i * r, r + i * r);
System.out.println(block);
int power = block.length() - 1;
int representation = 0;
for(int j = 0; j < block.length(); j ++){
String currentLetter = block.substring(j,j+1);
int letterValue = alphabet.indexOf(currentLetter);
representation += letterValue * Math.pow(26, power);
power--;
}
encodedBlocks.add(representation);
}
System.out.println("Encoded blocks are as follows: ");
for(int num : encodedBlocks){
System.out.println(num);
}
}
}
```
The output of the above code is `SUPPLIES: 6639182 5837362 7923517 8463981 3588695 8358510"` and this is the encoded vesion of our flag. So analyzed the code and reversed the encoding program.
My observations are, the above code is doing generating a integer for for a block of characters. That is `6639182` is on encoded version of a block of characters. This is generated by accessing the index of the character from alphabet string and this is multiplied `pow(26,power)` where `power=len(block)-1` and this power is decreased for every new character in the block.
Okay, lets have some math. lets assume block size = 4
power = 3
the initial encoded block value will become
`index(char)x26^3 + index(char)x26^2 + index(char)x26^1 + index(char)x26^0`
Simply it is doing a `base26` operation. So, in the decode program, we have to perform decoding of base26.
This is the solution script which can give the decoded message from encoded blocks.
```python
import string
alphabet = string.ascii_lowercase
input_str = input("Enter numerical blocks to be decoded (separated by spaces): ")
# split input into individual numerical blocks
input_blocks = input_str.split(" ")
decoded_blocks = []
for block in input_blocks:
num = int(block)
decoded = ""
while num > 0:
remainder = num % 26
decoded_letter = alphabet[remainder]
decoded = decoded_letter + decoded
num //= 26
decoded_blocks.append(decoded)
# combine decoded blocks into original message
decoded_message = "".join(decoded_blocks)
print("Decoded message: " + decoded_message)
#6639182 5837362 7923517 8463981 3588695 8358510
# onthemuddyriversnorthwestshore
# jctf{onthemuddyriversnorthwestshore}
```
> `Flag : jctf{onthemuddyriversnorthwestshore}`
## [Original Writeup](https://themj0ln1r.github.io/posts/jerseyctf23)