This is one of the projects I almost forgot about. It was the first time I used programming to my advantage, so very happy and nostalgic to write about it.
The Contest
Back in 2015, I saw an advertisement for a local company of last-minute flights that made the following Contest: For a week, each day they will publish a riddle. The answer is a city in the world which one of the flights to this city will be sold for 1$.
To find it, you need to use their app, choose departure and return dates and click search.
If you are lucky enough, as the result you would see the 1$ flight.
First Attempts
In the beginning, I thought the riddle is going to be the most challenging part, but the first riddle was something like "In which city is the Eiffel Tower located?"
So, after the first day, I realized I was naive and the purpose of the contest is, of course, marketing the app and not making head breaker riddles.
On the first day, I tried to find the flight just by brute-forcing the possible dates. Needless to say, it didn’t work and while I barely finished one month I saw that winners had already been declared on their Facebook page.
Trying brute-forcing with one phone wasn’t very practical so the next day I talked about the contest to a couple of friends and we divided the dates between us and tried to find the 1$ flight. And of course, we didn’t find the flight…
Decompiling The App
I started thinking of an alternative way to find the dates of the 1$ flight. So, I decided to decompile the app and thought that maybe I’ll find the answer. I had no experience with reverse engineering, or with app development but I thought I should give it a try.
I tried some APK (android package) decompilers and started to look at the app. I didn’t know what I’m looking for and just went through the files and tried to understand something.
I didn’t find anything… and another day passed.
Collecting small hints
A couple of days passed and I was trying to think about ways to get an advantage in finding the flight. I looked at the destination cities of the past days and noticed that for all of them easyJet had direct flights from Tel-Aviv.
So, I deduced that the next cities would also be cities that easyJet has a direct flight to. I listed all of those cities and decided to try making a more efficient system for searching flights.
Programming Skills
Before I write about the solution I found, a bit about my programming skills at the time. I started to learn to program in high school when I was 15. At that point, I was 17 and all my knowledge came from school classes.
I learned JAVA and knew very basic concepts, such as variable types, ifs, for, while and arrays. As you can see, I had very basic knowledge that every person could learn in a matter of days.
The Script
I wanted to make the searching more efficient and I had the following assumptions in mind:
- The city should be within easyJet direct flights from Tel-Aviv.
- It is more likely to be a cheap flight
- The duration should not be more than one week
I wrote a script that mainly helped me with organizing the data.
For each city I entered the price of the flight (departure and return) for each date, then the script calculates each combination of dates and prints the dates and price. Then, based on the prices, it sorts and prints the result.
Here is most of the code I wrote back then (was very surprised to find it in my inbox, probably because of what happened afterward)
int [][] Dep= new int [][]{
new int []{},
new int [] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31},
new int [] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29},
new int [] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31},
new int [] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30},
new int [] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31},};
int [][] Ret= new int [][]{
new int []{},
new int [] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31},
new int [] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29},
new int [] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31},
new int [] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30},
new int [] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31},};
int m=0;int q=0;
System.out.println("הכנס מחירי טיסות יוצאות, אם אין טיסה הכנס 0");
//enter depurture filght prices, if no flight, enter 0
for (int i=1;i<Dep.length;i++)
for (int j=0;j<Dep[i].length;j++)
{q=j+1;
System.out.println("מחיר טיסה בחודש "+i+" ביום "+q);
//enter price of flight in day j in month i
Dep[i][j]=reader.nextInt();
}
System.out.println("הכנס מחירי טיסות חוזרת, אם אין טיסה הכנס 0");
//enter return filght prices, if no flight, enter 0
for (int i=1;i<Ret.length;i++)
for (int j=0;j<Ret[i].length;j++)
{q=j+1;
System.out.println("מחיר טיסה בחודש "+i+" ביום "+q);
//enter price of flight in day j in month i
Ret[i][j]=reader.nextInt();
}
String [] Calc= new String [320];
int s=0;
for(int i=0;i<320;i++)
{
Calc[i]="";
}
int y=0;int f=0;int l=0;
for (int i=1;i<Dep.length;i++)
for(int j=0;j<Dep[i].length;j++)
for (int k=1;k<7;k++)
{q=j+1;
m=j+k+1;
if (m>=Dep[i].length)
{ s=m-Dep[i].length;
if(Dep[i][j]!=0 && Ret[i+1][s]!=0)
{y=i+1;
l=s+1;
Calc[Dep[i][j]+Ret[i+1][s]]+=q+"/"+i+"-"+l+"/"+y+", ";
}
}
else
if(Dep[i][j]!=0 && Ret[i][j+k]!=0)
{
f=m+1;
Calc[Dep[i][j]+Ret[i][j+k]]+=q+"/"+i+"-"+f+"/"+i+", ";
}
}
As you can see the script isn’t pretty and quite messy, but it did the job. I put it here to show that it is fine if your code isn’t the prettiest or the most organized, if it fulfills your initial goal, then fine.
Over the years, Of course, you develop better habits for writing readable and more organized code, but as you know most of us start writing messy scripts like this, and it’s fine.
Finding The 1$ Flight
After writing the script, for each city, I had a list of dates of flights sorted from the cheapest, for example
Paris
23/1-25/1, Price:150
23/1-30/1, Price:181
16/1-23/1, Price:184
18/1-25/1, 20/1-25/1, Price:205
25/1-30/1, Price:212
12/3-14/3, Price:214
27/1-30/1, Price:229
13/1-16/1, Price:230
9/1-10/1, 9/1-16/1, 18/1-23/1, 20/1-23/1, Price:232
11/1-16/1, Price:238
6/1-10/1, Price:290
After I made the list, I took a couple of my family’s phones and searched with them simultaneously for flights.
A couple of days came by without success in finding the 1$ flight… On 13.12.2015 the destination was Geneva, and I was able to find the 1$ flight using the list I made!!!
In orange it is written Tel Aviv <==> Geneva, 12/05/2016 – 15/05/2016
And as you can see, 1$ flight :). (1$ per person per direction 4$)
Winning #1 | Winning #2 |
---|---|
I was super excited, but there was more to come… when I tried to order the flight I got an error message from the server. I became upset and frustrated but I quickly filmed the screen for evidence for later conversation with the company (One good thing about the situation was that due to this I have documentation of finding of the 1$ flight).
Later that day I contacted the company and told them about what happened. They said that what probably happened is that someone found the flight before me but didn’t finish the ordering, so it was still available on the website.
In their favor, I would tell that they understood my claim and gave me a 100$ discount for purchasing 2 flight tickets.
Extra Thoughts
programming at any level
This was a great experience, I liked one specific thing about it, how I used programming in my favor. This was the first time I felt how programming gave me an advantage in achieving my goal.
As you can see, all the programming was very basic, and every beginner programmer could have written this script. This emphasizes that you don’t need to be a super experienced programmer to get an advantage from programming, but you will need to be creative to gain more advantage from other areas.
Combining some small details about the flights (EasyJet, cheap flights, no more than a week), a script, and some luck, enabled me to find the 1$ flight.
When I try to win this kind of challenges, I always feel intimidated and think I don’t know enough about web exploiting, reverse engineering, or other security topics. But sometimes a creative idea can help you overcome the pure skills needed.
Keep making and until the next project, roto