Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
467 views
in Technique[技术] by (71.8m points)

reverse engineering - How to decode some number into timeDate?

This question is sequel of this one.

So any idea how to decode this number 5252235562500 into date and time 19.11.2010 15:43 ? I have more pairs like this and I'm thinking about some script for comparing them to find some patern. Any advice what to check and how to search for patterns ?


EDIT: I added four pairs that I curentlly have.

  • 11.11.2010 16:23 > 5252425372575
  • 16.11.2010 15:30 > 5252922462564
  • 19.11.2010 15:39 > 5252231562511
  • 19.11.2010 15:43 > 5252235562500
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think I found the solution. Instead of simply presenting the decoding algorithm I'd like to show you the reasoning.

The answer to the linked question showed that was a barcode in EAN-13 format.

It means the codes have 12 digits and 1 check digit:

11.11.2010 16:23 > 525242537257 5
16.11.2010 15:30 > 525292246256 4
19.11.2010 15:39 > 525223156251 1
19.11.2010 15:43 > 525223556250 0

The check digit can be calculated by

  • adding the values of the digits in the even-numbered positions: 2, 4, 6 ... (2+2+2+3+2+7=18)
  • multiplying this result by 3 (18*3=54)
  • adding the values of the digits in the odd-numbered positions: 1, 3, 5... (5+5+4+5+7+5=31)
  • summing the two results (54+31=85)
  • calculating modulo 10 and subtracting it from 10 (5-10=5)

I calculated the check digit for every code, it matched and confirmed the codes were in EAN-13 format.

According to the specification, the first two or three digits of the code could be country codes, so I tried to separate these:

11.11.2010 16:23 > 52 5242537257 5 | 525 242537257 5
16.11.2010 15:30 > 52 5292246256 4 | 525 292246256 4
19.11.2010 15:39 > 52 5223156251 1 | 525 223156251 1
19.11.2010 15:43 > 52 5223556250 0 | 525 223556250 0

The resulting numbers didn't make any sense, because the earlier time had a greater number:
5292246256 or 292246256
than the later time:
5223156251 or 223156251

At this point I suspected the time wasn't stored in binary format. I reorganized the digits and tried to find repeating patterns.
I ended up with this layout:

11.11.2010 16:23 > 52 52 42 53 72 57 5
16.11.2010 15:30 > 52 52 92 24 62 56 4
19.11.2010 15:39 > 52 52 23 15 62 51 1
19.11.2010 15:43 > 52 52 23 55 62 50 0

This is where things got interesting...

Take a look at the 3rd and 4th row, these are the same except the 4th and 6th column.
The 4th column has 15 and 55. Translate it backwards and you get 51 and 55.
The difference of the two is 55 - 51 = 4 just like the difference of minutes 43 - 39 = 4
Subtract the minutes from code values:
55 - 43 = 12
51 - 39 = 12

It seems the 4th column encodes minutes by adding 12 and storing the digits backwards.

Now try to apply this to the 5th column:

11.11.2010 16:23 > 72 > 27
16.11.2010 15:30 > 62 > 26
19.11.2010 15:39 > 62 > 26
19.11.2010 15:43 > 62 > 26

26 - 15 = 11 and 27 - 16 = 11 so the difference for the 5th column is 11.

From then it's easy, the differences for the columns are 15, 14, 13, 12 & 11.
A few quick calculations and you get the encoding scheme:

Digits Meaning Diff.
 2-1    year    15
 4-3    month   14
 6-5    day     13
 8-7    minute  12
10-9    hour    11

Here's a simple code snippet for decoding:

union TimeFormat
{
    unsigned short codearray[5];
    struct
    {
        unsigned short year;
        unsigned short month;
        unsigned short day;
        unsigned short minute;
        unsigned short hour;
    };
};

void DecodeBarcode(char *code, TimeFormat *time)
{
    char buf[3]; // for atoi()
    buf[2] = 0;  // of course it has to be null-terminated

    for (int i = 0, diff = 15; i < 5; ++i, --diff)
    {
        buf[0] = code[i * 2 + 1];
        buf[1] = code[i * 2];
        time->codearray[i] = atoi(buf) - diff;
    }
    time->year += 2000;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...