raw gps, again

Thx to the anonymous guy who commented here. I'm now able to get the coordinates from my GPS mouse in the format eg. google maps wants it. According to this article, which i just read today, there are three ways GPS coordinates are expressed.
One is decimal (looks like 83.5672 N 48.4532 W) This one is easy for computers to understand. The second is degree-minutes-seconds, which looks like 38° 53' 23" N, 77° 00' 32" W. The last is degree minutes (N 38° 23.5674' W 83° 43.5612') You may think that the GPS is outputting decimal, right? Wrong! It is actually degree-minutes with the punctuation omitted. If the GPS Says its at 4008.5398 N 08304.7582 W, then it is really N 40° 08.5398' W 83° 04.7582'. Just add a degree sign two digits before the decimal point.
 If you look at the raw output from your GPS device you can see something like that.
cat /dev/ttyACM3

latitude: 4253.0970 N
longitude: 01032.3917 E

To transform them into the right format first get the numbers before the point position minus 2.
(Not 100% sure if that's right?!)
4253.0970 = 42° ==> 53.0970 is left
01032.391 = 010° = 10° ==> 32.391 is left

Next, divide the rest by 60.
53.0970/60 = 0,88495
32.391/60 = 0,53985

Now just put them together do get the decimal degrees format
42,88495   10,53985
Last make sure if latitude is South, put and minus before that number. Same goes for longitude if it's West.
I wrote a bash script that reads from the device and does the job.

 while read line;do  
      raw=$(echo $line | grep GPGGA | awk -F, '{printf "%f %f %s %s %s",$3,$5,$10,$4,$6}')  
      if [ -z "$raw" ];then  
           lat=$(echo $raw | awk '{printf $1}')  
           lon=$(echo $raw | awk '{printf $2}')  
           alt=$(echo $raw | awk '{printf $3}')  
           pointposlat=$(echo $lat | grep -b -o "\." | cut -d: -f1)  
           pointposlon=$(echo $lon | grep -b -o "\." | cut -d: -f1)       
           decmin1=$(echo "scale=6;${lat:2}/60" | bc)  
           decmin2=$(echo "scale=6;${lon:2}/60" | bc)   
           if [ $(echo $raw | awk '{printf $4}') = "S" ];then  
           if [ $(echo $raw | awk '{printf $5}') = "W" ];then  
           echo "Lat,Lon: $lat,$lon Alt: $alt"  
 done < $device  
Usage: [sudo] ./ device
Now you can feed it to maps

Please leave a comment if you see some mistakes or tips for optimization. Thank you.


Basic Vector Space Search Engine

...sounds more complicated than it actually is. It's a way to compare documents based on word frequency. I will try to explain the concept of this kind of engine based on a few articles i read, in particular this pdf. Why? Because i learned something at school that helped me to understand the paper. At school. Again @SCHOOL! Isn't that awesome! I have to write that down. :=)

Let say we have 3 documents. Each one contains combinations of the words cat, dog, mouse. Here is the count for each word in the document.

document 1
document 2
document 3

The next step is to make a vector space out of this information. Each word makes one dimension. It also works with more words, just make a dimension out of every word.

You can use the word counts in one document as a position in this 3D space. P3(2/3/0) becomes a position (P3 = Document 3), because document 3 contains 2 x cat, 3 x mouse and 0 x dog.
The Points P1-3 are now the peaks of the document vectors.

Now every document has it own document vector e.g. Document 1 vector is 0P1  (0 for Origin).
To calculate the length (magnitude) of this vector just do.

After we have the length of all document vectors we need the query vector. The query vector is basically the term we want to search for. I stay with the paper and use "mouse" as the query term.
Converted to a vector it would be Q(0/1/0). (mouse is in the second row in the table, query term "dog mouse" for example would become (0/1/1)).
Again we calculate the length of this query vector by doing

The final step is to build the cosine value between the document vector one and the query vector. This can be done with this formula.

(The circle in the numerator means you have to calculate the so called dot product or scalar product of these two vectors)
So lets calculate first the numerator which is the scalar product of the query vector and document 1 vector.

You can do this calculation the following way

(0*3) + (1*1) + (0*4) = 1

Now the denominator. Just multiply the length of the query vector with the length of the document 1 vector
|Q| * |D1| = 1 * 5,099019514 = 5,099019514

and so the cosine between the document 1 vector and the query vector is

If you repeat this for the other document vectors by doing

You get the other two cosine values and the one which is the closest to 1 tells you which is the most relevant document to your query term.

Document 1: cos = 0,1961161351
Document 2: cos = 0,3651483717
Document 3: cos = 0,8320502943 => most relevant

Now nothing stops you from making the next google!!1!1



Borderlands 2 serial guessing

A few weeks back i came across this little challenge on TheVamp's blog.
You can see a scratched Borderlands 2 Serial and the task was to find out the correct one and submit it there. After a while i came up with the bash script below. Don't read further if you wanna try it yourself first ; )

1:   #!/bin/bash  
2:   url="";  
4:   block1[0]="B";  
5:   block1[1]="GCQ";  
6:   block1[2]="COQ";  
7:   block1[3]="EFSB";  
9:   block2[0]="D";  
10:  block2[1]="OQ";  
11:  block2[2]="K";  
12:  block2[3]="A";  
14:  block3[0]="EFB";  
15:  block3[1]="G";  
16:  block3[2]="B";  
17:  block3[3]="O";  
19:  block4[0]="F";  
20:  block4[1]="U";  
21:  block4[2]="PRB";  
22:  block4[3]="L";  
24:  block5[0]="W";  
25:  block5[1]="UO";  
26:  block5[2]="FEB";  
27:  block5[3]="M";  
29:  block6[0]="B";  
30:  block6[1]="RB";  
31:  block6[2]="Z";  
32:  block6[3]="J";  
34:  # Total Number of Serials, tns
35:  tns1=`expr ${#block1[0]} \* ${#block1[1]} \* ${#block1[2]} \* ${#block1[3]}`;  
36:  tns2=`expr ${#block2[0]} \* ${#block2[1]} \* ${#block2[2]} \* ${#block2[3]}`;  
37:  tns3=`expr ${#block3[0]} \* ${#block3[1]} \* ${#block3[2]} \* ${#block3[3]}`;  
38:  tns4=`expr ${#block4[0]} \* ${#block4[1]} \* ${#block4[2]} \* ${#block4[3]}`;  
39:  tns5=`expr ${#block5[0]} \* ${#block5[1]} \* ${#block5[2]} \* ${#block5[3]}`;  
40:  tns6=`expr ${#block6[0]} \* ${#block6[1]} \* ${#block6[2]} \* ${#block6[3]}`;  
42:  tns=`expr $tns1 \* $tns2 \* $tns3 \* $tns4 \* $tns5 \* $tns6`;  
43:  echo "Total number of possible serials: $tns";  
45:  function createblock(){  
46:      block=("$@");  
47:      for ((b0=0;b0<${#block[0]};b0++))  
48:      do  
49:          for ((b1=0;b1<${#block[1]};b1++))  
50:          do  
51:              for ((b2=0;b2<${#block[2]};b2++))  
52:              do  
53:                  for ((b3=0;b3<${#block[3]};b3++))  
54:                  do  
55:                  bl=${block[0]:b0:1}${block[1]:b1:1}${block[2]:b2:1}${block[3]:b3:1};  
56:                  echo $bl;  
57:                  done  
58:              done  
59:          done  
60:      done  
61:  }  
63:  function checksearial(){  
64:      key=${serialblock1[b0]}-${serialblock2[b1]}-${serialblock3[b2]}-${serialblock4[b3]}-${serialblock5[b4]}-${serialblock6[b5]};  
65:      request="feld1="${serialblock1[b0]}"&feld2="${serialblock2[b1]}"&feld3="${serialblock3[b2]}"&feld4="${serialblock4[b3]}"&feld5="${serialblock5[b4]}"&feld6="${serialblock6[b5]}"&sub=send";  
66:      result=$(wget --post-data="$request" -qO- /dev/null;  
67:      if [[ "$result" != *falsch* ]]  
68:          then  
69:              echo -e "\n[+] FOUND CORRECT SERIAL ";  
70:              echo -e $key "\n";  
71:          exit;  
72:      else  
73:          echo "[*] Testing [$counter|$tns] $key";  
74:          ((counter++));  
75:      fi  
76:  }  
78:  # Generate all possible serialblocks  
79:  serialblock1+=(`createblock "${block1[@]}"`);  
80:  serialblock2+=(`createblock "${block2[@]}"`);  
81:  serialblock3+=(`createblock "${block3[@]}"`);  
82:  serialblock4+=(`createblock "${block4[@]}"`);  
83:  serialblock5+=(`createblock "${block5[@]}"`);  
84:  serialblock6+=(`createblock "${block6[@]}"`);  
86:  # Generate all possible serials  
87:  counter=1;  
88:  for ((b0=0;b0<${#serialblock1[@]};b0++))  
89:  do  
90:      for ((b1=0;b1<${#serialblock2[@]};b1++))  
91:      do  
92:          for ((b2=0;b2<${#serialblock3[@]};b2++))  
93:          do  
94:              for ((b3=0;b3<${#serialblock4[@]};b3++))  
95:              do  
96:                  for ((b4=0;b4<${#serialblock5[@]};b4++))  
97:                  do  
98:                      for ((b5=0;b5<${#serialblock6[@]};b5++))  
99:                      do  
100:                          checksearial;  
101:                      done  
102:                  done  
103:              done  
104:          done  
105:      done  
106:  done  

Line 4-27
6 Arrays, one for each block of the serial and every index got a value of a possible character which i guessed from the picture.

Line 36-40
Calculating all possible serials with the given input.
Example:   _  _  _
                 1  2  3
Position 1: O,C,Q      3
Position 2: A             1
Position 3: I,T           2

All possible values are...
OAI,OAT,CAI,CAT,QAI,QAT  Total of 3*1*2 = 6 possible values

Line 85-87 & 45-61 (createblock)
Creates for every block an array of possible values like the OAI, OAT,CA.... above and stores it in serialblocki

Line 88-106
Does almost the same as createblock but with all seriablocks so a complete serial accrues and calls checkserial

Line 63-76 (checkserial)
wgets the serial to the url and checks if the response has the string "falsch" (wrong) in it. If not so, you found the correct key

I'm sure there is space for optimization in this code but hey it works!
Let me know if you have an better nicer idea to solve that chall.
Thx @TheHaloVamp 4challWozPhun

Useful resources...