TeLeVision
Dissecting a Serialized TLV Array.
Last updated
Dissecting a Serialized TLV Array.
Last updated
We will write a seeking algorithm that takes in the file data.bin
, which contains a specialized array that has been serialized. The algorithm will read the array according to its rules. The flag can be printed out by printing the first, middle, and 8 characters of the string made using the below constraints.
You have been provided data.bin
which contains the serialized array. The array is a TLV (Tag-Length-Value) array, where each array contains a Tag, Length, and Value. Each element takes the following form:
The parts of the array entry are:
Tag: An identifier used to classify the incoming data type.
Length: The length of the value.
Value: The value of the data.
You should store all the array entries with prime number tags in a string. No delimiters should be used in between entries.
The flag is generated by printing the first, middle, and 8 characters of the string created. Hint: The string has an even length.
The flag will be represented in ASCII. Remember to surround your data in flag{}
braces.
You'll notice that this writeup won't define a struct
. In this case, we don't really need to. Because we only need to store the value of the items that satisfy a condition (being prime), we can just store the values we find.
For this challenge, we need to read the data as normal:
Open the file and ensure it's properly opened
Initialize the container
Read the data using an infinite while loop
First, we open the file. Nothing new here.
Then, we initialize the container. The instructions said to store the entries in a string, so I made a large string. It's infeasible to predict the number of elements for two reasons:
The size of each ArrayItem is based on length
We don't know which of the tags are prime
I chose an arbitrarily large number (10000). The file is only 8.6 kilobytes, so this number is more than large enough.
Now, we read the data. Since we don't know the number of elements to read, we use an infinite while loop. Rather than tracking the number of elements read, we track the index we are at in the string so we know where to write for each iteration.
When we read the data, we must check if a number is prime at the time of reading. If the number is prime, we should copy it from the variable into the string, starting at index
.
Defining the isPrime
function is simple. We simply can check if the number is divisible by any number between 2 and the number itself. If you want to optimize this further, you only need to check between 2 and sqrt(n)
. You'll need the math package for this.
Surprisingly, this is all the processing we need for this section. We can move on to printing the flag.
Printing the flag is a bit difficult. We need the first, middle, and last 8 characters of the string. We're provided the hint that the string has an even length so that we can use this to our advantage. Let's think about the format of a small string:
How can we print these out?
For the first 8, we can iterate starting at index 0
and go 8
elements.
For the last 8, we can count backward 8
from the end of the string and start there.
For the middle 8, we need to find the middle of the string, move 8/2
to the left, and then iterate 8
elements.
Here's how we can make this work. I chose to use a variable for the characters per section (cps
) to have more expandable code.
Running this gets the flag:
Here is the full solution: