DES encryption function give me a cipher text that is wrong - encryption

I have written the DES algorithm in haskell, but when i tried it, it doesn't give the correct output, i have tested every function on its own, they seem to work correctly, i have taken a message to encrypt: plainText = 123456ABCD132536 with the key = AABB09182736CCDD, when encrypted with DES it suppose to give me as output cipherText = C0B7A8D05F3A829C. The subkeys are all (K1..K16) correct, l0, r0 are correct as well , so are l1, r1 , l2, r2 , but at round 3 , i get r3 = B00A9591 , but its supposed to be B8089591 according to a tutorial that i follow.
(we have r2 = 4A1210F6, after expansion it becomes 2540A40A17AC, after the XOR with the subkey k3 = 6EDA4ACF5B5 we get 23AD00A6E219, after substitution we get 232713FA , after the straight permutation we get EA727605, and finaly an xor with l2 = 5A78E394 we get B00A9591)
At which point is it incorrect?even if i do it by hand i get the same results, i didn't understand what the problem is because the functions used at round 3 are the same used at round 1 and 2 without any problem. Can someone give me the correct value of r3, and any ideas of what could be the problem?it took me a very long time. Thank you.

This is done from a copy of Eugene Styer's JavaScript DES Example that has been modified to allow the key to be entered by removing the read-only attributes and default values. A copy of the original code allowing the key to be set used to be available on Google Code.
It produces the output ciphertext c0b7a8d05f3a829c
Round 3
E : 001001 010100 000010 100100 000010 100001 011110 101100 2540A40A17AC
KS : 000001 101110 110110 100100 101011 001111 010110 110101 06EDA4ACF5B5
E xor KS: 001000 111010 110100 000000 101001 101110 001000 011001 23AD00A6E219
Sbox: 0010 0011 0010 0111 0001 0011 1111 0000 232713FA (should be 232713F0)
P : 11100010 01110000 01110110 00000101 EA727605 (should be E2707605)
L[i]: 01001010 00010010 00010000 11110110
R[i]: 10111000 00001000 10010101 10010001
Your outputs in hexidecimal have been annotated and tell us row 01 index 12 (1100) of S Box 8 is producing an output of 1010 when it should be 0000.
S Box 8 values from FIPS Pub 46:
13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
The second row down, the 13th column element.
For a 6 bit input 011001 labelled B1 through B6, The row is found by concatenating B1 and B6 (01 or row 1 counting from 0), the column by concatenating B2 through B5 (1100).
The difference in the following P permutation is accounted for by the two unexpected '1' bits.
Without a Minimal Complete and Verifiable example it's not possible to determine if that is the sole error.
See vhdl - Data Encryption Standard test vectors - Stack Overflow for information on test vectors that allow among other things, testing S Boxes with a key comprised of all zeros. (The dropbox link in the last paragraph of the answer is still valid.)
The diff showing the modifications to JS-DES.html:
623c623
< <td><input name="key" value="0000000000000000" size="25" type="text"></td>
---
> <td><input name="key" value="3b3898371520f75e" readonly="readonly" size="25" type="text"></td>
627c627
< <td><input name="keyb" value="0000000000000000" size="25" type="text"></td>
---
> <td><input name="keyb" value="922fb510c71f436e" readonly="readonly" size="25" type="text"></td>

Related

3DES Decryption Returning Encrypted Characters at End of Decrypted Password

I'm having a problem with password decryption that has worked correctly for some 10 years in a VB6 DLL but now on newer, faster servers, it's returning the last few encrypted characters of the stored password. For example, "1234" is stored as "Žl¹è=" but when that is decrypted it's coming back with "1234 ¹è=". This code was written well before I started working with the program and I know little about encryption/decryption.
What appears to be the relevant code is shown below:
'Prepare sCryptBuffer for CryptDecrypt
lCryptBufLen = Len(sInputBuffer)
sCryptBuffer = String(lCryptBufLen, vbNullChar)
LSet sCryptBuffer = sInputBuffer
'Decrypt data: lHkey=Encryption Key, 0 = No Hash, 1=True (for final?), 0=dwFlags?, sCryptBuffer=data to be decrypted, lCryptBufLen=length of the pbData buffer
If Not CBool(CryptDecrypt(lHkey, 0, 1, 0, sCryptBuffer, lCryptBufLen)) Then
GoTo Finished
End If
'Setup output buffer with just decrypted data
strDecryptedText = Mid$(sCryptBuffer, 1, GetResultsBufferLength(sInputBuffer))
strDecryptedText = Replace(strDecryptedText, vbNullChar, "")
'If the last characters ASCII value is 8 or less, this number represents the amount
'of padding that is on the decrypted text.
If Asc(Right(strDecryptedText, 1)) <= 8 Then
DecryptEx = Left(strDecryptedText, Len(strDecryptedText) - Asc(Right(strDecryptedText, 1)))
Else
DecryptEx = strDecryptedText
End If
The GetResultsBufferLength function appears to use the following line of code for 3DES:
lngReturn = lngTempLength - ((lngTempLength + 8) Mod 8) + 8
Any ideas will be much appreciated.

Counting observations using multiple BY groups SAS

I am examining prescription patterns within a large EHR dataset. The data is structured so that we are given several key bits of information, such as patient_num, encounter_num, ordering_date, medication, age_event (age at event) etc. Example below:
Patient_num enc_num ordering_date medication age_event
1111 888888 07NOV2008 Wellbutrin 48
1111 876578 11MAY2011 Bupropion 50
2222 999999 08DEC2009 Amitriptyline 32
2222 999999 08DEC2009 Escitalopram 32
3333 656463 12APR2007 Imipramine 44
3333 643211 21DEC2008 Zoloft 45
3333 543213 02FEB2009 Fluoxetine 45
Currently I have the dataset sorted by patient_id then by ordering_date so that I can see what each individual was prescribed during their encounters in a longitudinal fashion. For now, I am most concerned with the prescription(s) that were made during their first visit. I wrote some code to count the number of prescriptions and had originally restricted later analyses to RX = 1, but as we can see, that doesn't work for people with multiple scripts on the same encounter (Patient 2222).
data pt_meds_;
set pt_meds;
by patient_num;
if first.patient_num then RX = 1;
else RX + 1;
run;
Patient_num enc_num ordering_date medication age_event RX
1111 888888 07NOV2008 Wellbutrin 48 1
1111 876578 11MAY2011 Bupropion 50 2
2222 999999 08DEC2009 Amitriptyline 32 1
2222 999999 08DEC2009 Escitalopram 32 2
3333 656463 12APR2007 Imipramine 44 1
3333 643211 21DEC2008 Zoloft 45 2
3333 543213 02FEB2009 Fluoxetine 45 3
I think it would be more appropriate to recode the encounter numbers into a new variable so that they reflect a style similar to the RX variable. Where each encounter is listed 1-n, and the number will repeat if multiple scripts are made in the same encounter. Such as below:
Patient_num enc_num ordering_date medication age_event RX Enc_
1111 888888 07NOV2008 Wellbutrin 48 1 1
1111 876578 11MAY2011 Bupropion 50 2 2
2222 999999 08DEC2009 Amitriptyline 32 1 1
2222 999999 08DEC2009 Escitalopram 32 2 1
3333 656463 12APR2007 Imipramine 44 1 1
3333 643211 21DEC2008 Zoloft 45 2 2
3333 543213 02FEB2009 Fluoxetine 45 3 3
From what I have seen, this could be possible with a variant of the above code using 2 BY groups (patient_num & enc_num), but I can't seem to get it. I think the first. / last. codes require sorting, but if I am to sort by enc_num, they won't be in chronological order because the encounter numbers are generated by the system and depend on all other encounters going in at that time.
I tried to do the following code (using ordering_date instead because its already sorted properly) but everything under Enc_ is printed as a 1. I'm sure my logic is all wrong. Any thoughts?
data pt_meds_test;
set pt_meds_;
by patient_num ordering_date;
if first.patient_num;
if first.ordering_date then enc_ = 1;
else enc_ + 1;
run;
First
.First/.Last flags doesn't require sorting if data is properly ordered or you use NOTSORTED in your BY statement. If your variable in BY statement is not properly ordered then BY statment will throw error and stop executing when encounter deviations. Like this:
data class;
set sashelp.class;
by age;
first = first.age;
last = last.age;
run;
ERROR: BY variables are not properly sorted on data set SASHELP.CLASS.
Name=Alfred Sex=M Age=14 Height=69 Weight=112.5 FIRST.Age=1 LAST.Age=1 first=. last=. _ERROR_=1 _N_=1
NOTE: The SAS System stopped processing this step because of errors.
NOTE: There were 2 observations read from the data set SASHELP.CLASS.
Try this code to see how exacly .first/.last flags works:
data pt_meds_test;
set pt_meds_;
by patient_num ordering_date;
fp = first.patient_num;
lp = last.patient_num;
fo = first.ordering_date;
lo = last.ordering_date;
run;
Second
Those condidions works differently than you think:
if expression;
If expression is true then continue with next instructions after if.
Otherwise return to begining of data step (no implicit output). This also implies your observation is not retained in the output.
In most cases if without then is equivalent to where. However
whereworks faster but it is limited to variables that comes from data set you are reading
if can be used with any type of expression including calculated fields
More info:: IF
Statement, Subsetting
Third
I think lag() function can be your answear.
data pt_meds_test;
set pt_meds_;
by patient_num;
retain enc_;
prev_patient_num = lag(patient_num);
prev_ordering_date = lag(ordering_date);
if first.patient_num then enc_ = 1;
else if patient_num = prev_patient_num and ordering_date ne prev_ordering_date then enc_ + 1;
end;
run;
With lag() function you can look what was the value of vairalbe on the previos observation and compare it with current one later.
But be carefull. lag() doesn't look for variable value from previous observation. It takes vale of variable and stores it in a FIFO queue with size of 1. On next call it retrives stored value from queue and put new value there.
More info: LAG Function
I'm not sure if this hurts the rest of your analysis, but what about just
proc freq data=pt_meds noprint;
tables patient_num ordering_date / out=pt_meds_freq;
run;
data pt_meds_freq2;
set pt_meds_freq;
by patient_num ordering_date;
if first.patient_num;
run;

R: How to read in a PGN as a Data Frame

I have a single .pgn Portable Game Notation of a large number of chess games. The games are contained in the file like this:
[Event "4th Bayern-chI Bank Hofmann"]
[Site "?"]
[Date "2000.10.29"]
[Round "?"]
[White "Carlsen, Magnus"]
[Black "Cordts, Ingo"]
[ECO "A56"]
[WhiteElo "0"]
[BlackElo "2222"]
[Result "0-1"]
1. d4 Nf6 2. c4 c5 3. Nf3 cxd4 4. Nxd4 e5 5. Nb5 d5 6. cxd5 Bc5 7. N5c3 O-O 8. e3 e4 9. h3 Re8 10. g4 Re5 11. Bc4 Nbd7 12. Qb3 Ne8 13. Nd2 Nd6 14. Be2 Qh4 15. Nc4 Nxc4 16. Qxc4 b5 17. Qxb5 Rb8 18. Qa4 Nf6 19. Qc6 Nd7 20. d6 Re6 21. Nxe4 Bb7 22. Qxd7 Bxe4 23. Rh2 Bxd6 24. Bc4 Rd8 25. Qxa7 Bxh2 26. Bxe6 fxe6 27. Qa6 Bf3 28. Bd2 Qxh3 29. Qxe6+ Kh8 30. Qe7 Bc7
0-1
[Event "4th Bayern-chI Bank Hofmann"]
[Site "?"]
[Date "2000.10.30"]
[Round "?"]
[White "Kaiser, Guenter"]
[Black "Carlsen, Magnus"]
[ECO "A46"]
[WhiteElo "0"]
[BlackElo "0"]
[Result "0-1"]
1. d4 Nf6 2. Nf3 d6 3. Nc3 g6 4. e4 Bg7 5. Be2 O-O 6. O-O e5 7. Be3 h6 8. Qd2 Ng4 9. d5 f5 10. exf5 gxf5 11. h3 Nxe3 12. Qxe3 e4 13. Nd4 Qe7 14. Rad1 c5 15. dxc6 bxc6 16. Bc4+ Kh7 17. Nce2 d5 18. Bb3 c5 19. Nb5 d4 20. Qd2 Bb7 21. Nf4 a6 22. Nd5 Qe5 23. Nbc7 Ra7 24. Qa5 Nd7 25. g3 Rc8 26. Nb5 Raa8 27. Nbc7 Bxd5 28. Nxa8 Rxa8 29. Ba4 Be6 30. Kh2 f4 31. Qe1 Nf6 32. Bc6 Rc8 33. Bb7 Rc7 34. Ba8 Bd5 35. Bxd5 Nxd5 36. Qe2 fxg3+
0-1
I would like to read in this data as a DataFrame where the column titles are simply the word to the left of the string in quotation marks and the row values are whatever is in the quotation marks. Another column would contain a string of all the moves.
I am completely new to R and simply cannot figure out how to read in a file that is not already in some known format.
readLines() looks promising.
Try this:
pgn <- read.table("your_file.pgn", quote="", sep="\n", stringsAsFactors=FALSE)
# get column names
colnms <- sub("\\[(\\w+).+", "\\1", pgn[1:12,1])
# give columns 11 (the moves) and 12 (redundant results column) nice names
colnms[11] <- "Moves"
colnms[12] <- "Results2"
pgn.df <- data.frame(matrix(sub("\\[\\w+ \\\"(.+)\\\"\\]", "\\1", pgn[,1]),
byrow=TRUE, ncol=12))
names(pgn.df) <- colnms
This solution assumes each game is 12 lines, as in your example. If games take up a variable numbers of lines, this solution won't work.
Explanation of the regex lines (see ?regex for more):
sub("\\[(\\w+).+", "\\1", pgn[1:12,1])
In this regex, we want the first word that follows a square bracket. We have to escape that bracket, as it's a metacharacter. There are other ways to achieve that without using escapes (\), such as by making the [ a character class by putting it inside square brackets: sub("[[](\\w+).+", "\\1", pgn[1:12,1]).
The parentheses (a capture group) go together with the \\1. The \\1 as the second argument to sub says to replace the original string with the contents of the first (and only in this case) capture group. Were there to be a 2nd capture group, you'd use \\2 to reference it.
The contents of the capture group \\w+ are one or more (that's what the + means) word characters (represented by \\w). After the () we want to match the rest of the string, which we can do by looking for any character (that's what . means) one or more times (i.e. .+).
So, the regex finds the first square bracket and the first consecutive block of word characters, which we capture, followed by one or more of any other characters.
The second regex: "\\[\\w+ \\\"(.+)\\\"\\]"
Let's look at the first entry of pgn[,1]: [1] "[Event \"4th Bayern-chI Bank Hofmann\"]". We start out the same as the first regex, but this time we don't want to capture the first word, we just want to find it followed by a space, and then we want to capture everything between the two sets of \".
Both \ and " have to be escaped, so we have a pair of \\\" surrounding a capture group that looks for any character one or more times (.+), and finally we have a square bracket, which we escape the same way as the first square bracket. If we didn't escape the ", R would think that was the end of the first argument to sub, and not interpret the " as a literal quote.
In the case of entries like line 11 and 12, nothing is matched because neither line starts with a [, and so, nothing is substituted. We just get the original string back in its entirety.
Here's what I'd try:
con = file("pgn_file.txt", "r")
all_lines = readLines(con)
close(con);
res = list();
for(this_line in all_lines)
{
if(grepl("^\\s*$", this_line, perl=T))
{
print("Empty line: do nothing")
}else
{
if(grepl("^\\[", this_line, perl=T))
{
field = gsub("^\\[\\s*([a-zA-Z]+)\\s*\"([a-zA-Z0-9\\s.?, -]+)\"\\]$", "\\1", this_line);
value = gsub("^\\[\\s*([a-zA-Z]+)\\s*\"([a-zA-Z0-9\\s.?, -]+)\"\\]$", "\\2", this_line);
print(field);
res[[tolower(field)]] = c(res[[tolower(field)]], value);
}else
{
print(this_line)
}
if(grepl("^1\\.", this_line, perl=T))
{
res[["move_list"]] = c(res[["move_list"]], this_line);
}
}
}
res = as.data.frame(res);

Questions about hexadecimal

Write a program to swap odd and even bits in an integer.
For exp, bit 0 and bit 1 are swapped, bit 2 and bit 3 are swapped.
The solution uses 0xaaaaaaaa and 0x55555555.
Can I know what does 0xaaaaaaaa and 0x55555555 means in binary number?
Each four bits constitutes a hex digit thus:
0000 0 1000 8
0001 1 1001 9
0010 2 1010 A
0011 3 1011 B
0100 4 1100 C
0101 5 1101 D
0110 6 1110 E
0111 7 1111 F
So, for example, 0x1234 would be 0001 0010 0011 01002.
For your specific examples:
0xaaaaaaaa = 1010 1010 ... 1010
0x55555555 = 0101 0101 ... 0101
The reason why a solution might use those two values is that, if you AND a value with 0xaaaaaaaa, you'll get only the odd bits (counting from the left), which you can then shift right to move them to the even bit positions.
Similarly, if you AND a value with 0x55555555, you'll get only the even bits, which you can then shift left to move them to the odd bit positions.
Then you can just OR those two values together and the bits have been swapped.
For example, let's start with the 16-bit value abcdefghijklmnop (each letter being a bit and with a zero bit being . to make it more readable):
abcdefghijklmnop abcdefghijklmnop
AND 1.1.1.1.1.1.1.1. AND .1.1.1.1.1.1.1.1
= a.c.e.g.i.k.m.o. = .b.d.f.h.j.l.n.p
>>1 = .a.c.e.g.i.k.m.o <<1 = b.d.f.h.j.l.n.p.
\___________ ___________/
\ /
.a.c.e.g.i.k.m.o
OR b.d.f.h.j.l.n.p.
= badcfehgjilknmpo
So each group of two bits has been swapped around. In C, that would be something like:
val = ((val & 0xAAAAAAAA) >> 1) | ((val & 0x55555555) << 1);
but, if this is classwork of some description, I'd suggest you work it out yourself by doing individual operations.
For an in-depth explanation of the bitwise operators that allow you to do this, see this excellent answer here.

What datetime format is this?

I have DateTime structure for an old data format that I don't have access to any specs for. There is a field which indicates the datetime of the the data, but it isn't in any format I recognize. It appears to be stored as a 32-bit integer, that increments by 20 for each day. Has anyone ever run across something like this?
EDIT:
Example: 1088631936 DEC = 80 34 E3 40 00 00 00 00 HEX = 09/07/2007
EDIT:
First off, sorry for the delay. I had hoped to do stuff over the weekend, but was unable to.
Second, this date format is weirder than I initially thought. It appears to be some sort of exponential or logarithmic method, as the dates do not change at an increasing rate.
Third, the defunct app that I have for interpreting these values only shows the date portion, so I don't know what the time portion is.
Example data:
(Hex values are big-endian, dates are mm/dd/yyyy)
0x40000000 = 01/01/1900
0x40010000 = 01/01/1900
0x40020000 = 01/01/1900
0x40030000 = 01/01/1900
0x40040000 = 01/01/1900
0x40050000 = 01/01/1900
0x40060000 = 01/01/1900
0x40070000 = 01/01/1900
0x40080000 = 01/02/1900
0x40090000 = 01/02/1900
0x400A0000 = 01/02/1900
0x400B0000 = 01/02/1900
0x400C0000 = 01/02/1900
0x400D0000 = 01/02/1900
0x400E0000 = 01/02/1900
0x400F0000 = 01/02/1900
0x40100000 = 01/03/1900
0x40110000 = 01/03/1900
0x40120000 = 01/03/1900
0x40130000 = 01/03/1900
0x40140000 = 01/04/1900
0x40150000 = 01/04/1900
0x40160000 = 01/04/1900
0x40170000 = 01/04/1900
0x40180000 = 01/05/1900
0x40190000 = 01/05/1900
0x401A0000 = 01/05/1900
0x401B0000 = 01/05/1900
0x401C0000 = 01/06/1900
0x401D0000 = 01/06/1900
0x401E0000 = 01/06/1900
0x401F0000 = 01/06/1900
0x40200000 = 01/07/1900
0x40210000 = 01/07/1900
0x40220000 = 01/08/1900
0x40230000 = 01/08/1900
....
0x40800000 = 05/26/1901
0x40810000 = 06/27/1901
0x40820000 = 07/29/1901
....
0x40D00000 = 11/08/1944
0x40D10000 = 08/29/1947
EDIT: I finally figured this out, but since I've already given up the points for the bounty, I'll hold off on the solution in case anyone wants to give it a shot.
BTW, there is no time component to this, it is purely for storing dates.
It's not integer, it's a 32 bit floating point number. I haven't quite worked out the format yet, it's not IEEE.
Edit: got it. 1 bit sign, 11 bit exponent with an offset of 0x3ff, and 20 bit mantissa with an implied bit to the left. In C, assuming positive numbers only:
double offset = pow(2, (i >> 20) - 0x3ff) * (((i & 0xfffff) + 0x100000) / (double) 0x100000);
This yields 0x40000000 = 2.0, so the starting date must be 12/30/1899.
Edit again: since you were so kind as to accept my answer, and you seem concerned about speed, I thought I'd refine this a little. You don't need the fractional part of the real number, so we can convert straight to integer using only bitwise operations. In Python this time, complete with test results. I've included some intermediate values for better readability. In addition to the restriction of no negative numbers, this version might have problems when the exponent goes over 19, but this should keep you good until the year 3335.
>>> def IntFromReal32(i):
exponent = (i >> 20) - 0x3ff
mantissa = (i & 0xfffff) + 0x100000
return mantissa >> (20 - exponent)
>>> testdata = range(0x40000000,0x40240000,0x10000) + range(0x40800000,0x40830000,0x10000) + [1088631936]
>>> from datetime import date,timedelta
>>> for i in testdata:
print "0x%08x" % i, date(1899,12,30) + timedelta(IntFromReal32(i))
0x40000000 1900-01-01
0x40010000 1900-01-01
0x40020000 1900-01-01
0x40030000 1900-01-01
0x40040000 1900-01-01
0x40050000 1900-01-01
0x40060000 1900-01-01
0x40070000 1900-01-01
0x40080000 1900-01-02
0x40090000 1900-01-02
0x400a0000 1900-01-02
0x400b0000 1900-01-02
0x400c0000 1900-01-02
0x400d0000 1900-01-02
0x400e0000 1900-01-02
0x400f0000 1900-01-02
0x40100000 1900-01-03
0x40110000 1900-01-03
0x40120000 1900-01-03
0x40130000 1900-01-03
0x40140000 1900-01-04
0x40150000 1900-01-04
0x40160000 1900-01-04
0x40170000 1900-01-04
0x40180000 1900-01-05
0x40190000 1900-01-05
0x401a0000 1900-01-05
0x401b0000 1900-01-05
0x401c0000 1900-01-06
0x401d0000 1900-01-06
0x401e0000 1900-01-06
0x401f0000 1900-01-06
0x40200000 1900-01-07
0x40210000 1900-01-07
0x40220000 1900-01-08
0x40230000 1900-01-08
0x40800000 1901-05-26
0x40810000 1901-06-27
0x40820000 1901-07-29
0x40e33480 2007-09-07
Are you sure that values correspond to 09/07/2007?
I ask because 1088631936 are the number of seconds since Linux (et al) zero date: 01/01/1970 00:00:00 to 06/30/2004 21:45:36.
Seems to me reasonable to think the value are seconds since this usual zero date.
Edit: I know it is very possible for this not to be the correct answer. It is just one approach (a valid one) but I think more info is needed (see the comments). Editing this (again) to bring the question to the front in the hope of somebody else to answer it or give ideas. Me: with a fairness, sportive and sharing spirit :D
I'd say that vmarquez is close.
Here are dates 2009-3-21 and 2009-3-22 as unix epochtime:
In [8]: time.strftime("%s", (2009, 3, 21, 1, 1, 0, 0,0,0))
Out[8]: '1237590060'
In [9]: time.strftime("%s", (2009, 3, 22, 1, 1, 0, 0,0,0))
Out[9]: '1237676460'
And here they are in hex:
In [10]: print("%0x %0x" % (1237590060, 1237676460))
49c4202c 49c571ac
If you take only first 5 digits, the growth is 21. Which kinda matches your format, neg?
Some context would be useful. If your data file looks something, literally or at least figuratively, like this file, vmarquez is on the money.
http://www.slac.stanford.edu/comp/net/bandwidth-tests/eventanalysis/all_100days_sep04/node1.niit.pk
That reference is data produced by Available Bandwith Estimation tool (ABwE) -- the curious item is that it actually contains that 1088631936 value as well as the context. That example
date time abw xtr dbcap avabw avxtr avdbcap rtt timestamp
06/30/04 14:43:48 1.000 0.000 1.100 1.042 0.003 1.095 384.387 1088631828
06/30/04 14:45:36 1.100 0.000 1.100 1.051 0.003 1.096 376.408 1088631936
06/30/04 14:47:23 1.000 0.000 1.100 1.043 0.003 1.097 375.196 1088632043
seems to have a seven hour offset from the suggested 21:45:36 time value. (Probably Stanford local, running on Daylight savings time.)
Well, you've only shown us how your program uses 2 of the 8 digits, so we'll have to assume that the other 6 are ignored (because your program could be doing anything it wants with those other digits).
So, we could say that the input format is:
40mn0000
where m and n are two hex digits.
Then, the output is:
01/01/1900 + floor((2^(m+1)-2) + n*2^(m-3)) days
Explanation:
In each example, notice that incrementing n by 1 increases the number of days by 2^(m-3).
Notice that every time n goes from F to 0, m is incremented.
Using these two rules, and playing around with the numbers, you get the equation above.
(Except for floor, which was added because the output doesn't display fractional days).
I suppose you could rewrite this by replacing the two separate hex variables m and n with a single 2-digit hex number H. However, I think that would make the equation a lot uglier.

Resources