Binary Date Time decode

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • flanagak
    New Member
    • Feb 2007
    • 4

    Binary Date Time decode

    All,

    I was wondering if someone could point me in the right direction to decode the following information.
    I am working on a tool writen in C and one of the items in the file I am decoding is a timestamp in this format.
    I had started looking at a bitfield structure, but I am wondering if there is a better / more portable solution.

    Hex Value in the file: 9D AF 79 C0
    Binary breakdown:
    1001(9) 1101(D) 1010(A) 1111(F) 0111(7) 1001(9) 1100(C) 0000(0)

    1001(9) 11011(27) 01011(11) 110111(55) 1(+) 00111(7) 000000(0)
    Decoded Value: 09/27 11:55 +07:00

    Format:

    These parameters indicate the time when the file was opened, according to the following binary format:
    • The first four binary bits indicate the month (1 .. 12), according to the CGF"s local time zone;
    • The next five binary bits contain the date (1 :: 31), according to the CGF"s local time zone;
    • The next five binary bits contain the hour (0 .. 23), according to the CGF"s local time zone;
    • The next six binary bits contain the minute (0 .. 59), according to the CGF"s local time zone;
    • The next bit indicates the sign of the local time differential from UTC (bit set to '1' expresses '+' or bit set to
    • The next five binary bits contain the hour (0 .. 23) deviation of the local time towards UTC, according to
    • The next six binary bits contain the minute (0 .. 59) deviation of the local time towards UTC, according to
  • DeMan
    Top Contributor
    • Nov 2006
    • 1799

    #2
    Have you gotten anywhere with it yourself so far? Please post your progress.

    This looks like it might need to use some bitshifts (which means fun for all the family), or at least some masking.

    Comment

    • RedSon
      Recognized Expert Expert
      • Jan 2007
      • 4980

      #3
      I would agree with the masking but I'm not sure what you are hoping to accomplish in terms of portability.

      Comment

      • flanagak
        New Member
        • Feb 2007
        • 4

        #4
        Wow you guys are fast ^_^.

        As for portability I was just concerned, after reading about bitfiled structurs that I may run into problems using this tool on other machines. All the systems that would use it should be x86 intel based systems so maybe it is not an issue.

        As for where I have gotten so far.
        Code:
        struct{
            unsigned month : 4;
            unsigned day : 5;
            unsigned hour : 5;
            unsigned minute : 6;
            unsigned diff : 1;
            unsigned dhour : 5;
            unsigned dmin : 6;
        } fTimestamp;
        Is the Structure I created in the headder file.

        Code:
        int memread(int len, FILE *in){
            unsigned char *buf; /* buffer */
            size_t result; /* Number of bytes read */
            int i;
            unsigned int val;
        
            if (len != 0){
                /* Allocate memory to store bytes read*/
                buf = ( unsigned char*) malloc (len);
                if (buf == NULL) {fputs ("Memory error",stderr); exit (2);}
        
                /* Read bytes into the buffer. Result holds number of bytes read */
                result = fread(buf,1,len,in);
        
                /* Display the value of each bit in hex and return 4 byte int value */
                for (i=0;i<result;i++){
                    printf("The value of byte %d = %02X \n",i+1, buf[i]);
                    if (result == 1) {
                        val = 1677721600;
                        val = (val * 256);
                        val += buf[i];
                    } else if (result == 2){
                        if (i == 0){
                            val = 3429105664;
                        }
                        val = (val * 256);
                        val += buf[i];
                    } else {
                        val = (val * 256);
                        val += buf[i];
                    }
                }
        
                /* Cleanup */
                free(buf);
            } else {
                val = 0;
            }
        
            return val;
        }
        Is the function I wotre to read the file in chucks based on specs for the file I was given.

        Code:
            file_length = memread(fLength,fp);
            printf("\nFile Length: %d \n", file_length);
            header_length = memread(hLength,fp);
            printf("Header Length: %d \n", header_length);
            high_version_id = memread(hVersion,fp);
            printf("High Version: %d \n", high_version_id);
            low_version_id = memread(lVersion,fp);
            printf("Low Version: %d \n", low_version_id);
            file_open_timestamp = memread(fOpenTime,fp);
            printf("File Open Timestamp: %u \n", file_open_timestamp);
        This is a few of the calling statemnts to the memread function.
        The length of each item is defined as a constatnt in the header file.
        Currently I am just printing the returned value to the screen.
        In the end I will be writing all the values out to a MySQL load file.

        The test I have done so far with the bitfiled values have showed me that whatever I pass to it it returs the binary value of the last n binary bits.
        So for fTimestamp.mont h if I assign it 22 (10110) fTimestamp returns a value of 6 (0110). Showing me that whatever I pass it assigns the last 4 bits.

        The reason for that test is that Im a bit stupmed how to break up the data to pass to the structure. Like fTimestamp.day is 5 bits binary, which from my 1st post would be the 4 bits from D (1101) and the 1st bit from A (1010) for a result of 27 (11011).

        So I guess the big roadblock for me is how to read the stream in a way to produce the correct values.


        Thanks for everyones input and suggestions

        Comment

        • DeMan
          Top Contributor
          • Nov 2006
          • 1799

          #5
          You can mask certain values away....
          If you have a bit string of length 16, say,: 1100 1101 0101 1100
          and you AND (&) it with 0000 0000 1111 0000, say, you get rid of the values you have 0 in your mask, and keep those that are one. You could do this for 5 bits int your time stamp, so that you isolate a particular 5.

          Once you have (and because we know the position int the bitstring), you can right (?) shift the value back as far as it needs. If you store it in a character variable (8 bits) you can easily get the value you require......

          Comment

          • DeMan
            Top Contributor
            • Nov 2006
            • 1799

            #6
            I probably should have added, that none of this requires you to explicitly work at the bit level......

            0000 0000 1111 0000 is an int with value 240(i think), and likewise any mask that you make, can be expressed as an integer......

            Comment

            • flanagak
              New Member
              • Feb 2007
              • 4

              #7
              Ok so with the data from above.
              The int value of the timestamp is 2645522880 or 100111011010111 101111001110000 00 in binary.

              So to get the first part of the timestamp ( the month) I would replace the last 28 bits with 0's, blanking out eveything but the 1st 4 and the shift it right to make those the last 4 bits?

              Also for the second element ( the day) I would mask out the 1st 4 and the last 23 with 0's, then shift right to amke those the last 5 bits?

              Comment

              • DeMan
                Top Contributor
                • Nov 2006
                • 1799

                #8
                Spot on. (take care with the bitshift for the leftmost value.....)


                (As a total Aside, FYI) You could actually do the shifting before the masking. Since you often need to use the same sizes eg 5, you may be able to create standardised masks to extract the 5 bits from 8. I would discourage you from taking this approach, though, as it involves casting big numbers into small numbers. whcih can have unexpected behaviour

                Comment

                • flanagak
                  New Member
                  • Feb 2007
                  • 4

                  #9
                  WORKS LIKE A CHARM..... Thank you
                  Here is what I ended up with and it works perfectly.

                  Code:
                      file_open_timestamp = memread(fOpenTime,fp);
                      printf("File Open Timestamp: %u \n", file_open_timestamp);
                      
                      fTimestamp.month = ((file_open_timestamp & 0xf0000000) >> 28);
                      fTimestamp.day = ((file_open_timestamp & 0x0f800000) >> 23);
                      fTimestamp.hour = ((file_open_timestamp & 0x007C0000) >> 18);
                      fTimestamp.minute = ((file_open_timestamp & 0x0003f000) >> 12);
                      fTimestamp.diff = ((file_open_timestamp & 0x00000800) >> 11);
                      fTimestamp.dhour = ((file_open_timestamp & 0x000007C0) >> 6);
                      fTimestamp.dmin = (file_open_timestamp & 0x0000003f);
                  
                      printf(" Month: %d \n",fTimestamp.month);
                      printf(" Day: %d \n",fTimestamp.day);
                      printf(" Hour: %d \n",fTimestamp.hour);
                      printf(" Minute: %d \n",fTimestamp.minute);
                      if (fTimestamp.diff == 1){
                          printf(" Diff: + \n");
                      } else {
                          printf(" Diff: - \n");
                      }
                      printf(" dHour: %d \n",fTimestamp.dhour);
                      printf(" dMin: %d \n",fTimestamp.dmin);
                  Here is the ouput from the 1st post.
                  File Open Timestamp: 2645522880
                  Month: 9
                  Day: 27
                  Hour: 11
                  Minute: 55
                  Diff: +
                  dHour: 7
                  dMin: 0

                  Comment

                  • DeMan
                    Top Contributor
                    • Nov 2006
                    • 1799

                    #10
                    Beautiful....

                    Comment

                    Working...