Photo Gallery Member List Search Calendars FAQ Ticket List Log Out


How do I? byte array converted to long, to date...

 
Logged in as: Guest
arrSession:exec spGetSession 2,2,40662
 Active Users: There are 0 members and 0 guests.
 Users viewing this topic: none
 

 

 
  
  Printable Version
All Forums >> [Scripting] >> WSH & Client Side VBScript >> How do I? byte array converted to long, to date...
  Do you like VisualBasicScript.com? Link to us and help spread the word about our forum. Thanks!
Page: [1] 2 3   next >   >>
Login
Message << Older Topic   Newer Topic >>
 How do I? byte array converted to long, to date... - 12/9/2006 4:51:40 PM   
  bofaboy

 

Posts: 16
Score: 0
Joined: 12/9/2006
Status: offline
Howdy,

I've got an array of ASCII string data in a log file file that I want to pull out and input to SQL for an application I monitor.. 

The problem is that the date coded in the file is a byte arraythat needs to be converted to a long int (seconds since epoch) 

68,116,53,22,0,0,17,36  --ascii character codes data

and I want to create a date out of it...

in Perl, I have prototyped the following code (if it helps):

$foo = pack("c8",68,116,53,22,0,0,17,36); #pack up the character/byte string
$foo2 = unpack("N",$foo); #convert the packed data structure to a long integer
$foo2 += 32768; #add 32768 because it seems as though the timing is slightly off for this application
print "foo2 = ".$foo2."\n"; #output the long int
print "foo2: " .scalar(localtime($foo2))."\n"; #output the date

output:
foo2 = 1148499222
foo2: Wed May 24 12:33:42 2006

-------------------

in my VB coding, I've tried this...

thisvar = Asc(68) & Asc(116) & Asc(53)& Asc(22) & Asc(0) & Asc(0) & Asc(17) & Asc(36)
foo2 = CLng(thisvar) -- should equal 1148466454 ---- ERRORS here..
foo2 = foo2 + 32768 'should equal 1148499222
print "foo2 (i) = "& foo2
print "foo2: (d) = " &   DateAdd("s", foo2, "01/01/1970 00:00:00")

output:

C:\Perl\Scripts\cdate.vbs(3, 1) Microsoft VBScript runtime error: Type mismatch:
'CLng'
 
 
Post #: 1
 
 RE: How do I? byte array converted to long, to date... - 12/9/2006 10:02:39 PM   
  TNO


Posts: 1397
Score: 16
Joined: 12/18/2004
From: thenewobjective.com
Status: offline
Well, the problem is that you are overloading the CLng function, use CDbl instead to handle a number this large:



      

_____________________________

To iterate is human, to recurse divine. -- L. Peter Deutsch

(in reply to bofaboy)
 
 
Post #: 2
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 2:48:24 AM   
  bofaboy

 

Posts: 16
Score: 0
Joined: 12/9/2006
Status: offline
Thanks for the reply..

Maybe the problem is that I'm not assigning thisvar correctly, but the perl code works as excected.  the math from the packed/unpacked values do equal correct value.

I'm just not sure how to do it in VB.

Yes, you're right the CDbl corrects the error, but gives me a number that is totally out of whack.  the number should be 1148499222..  because ...

WScript.Echo "foo2: (d) = " &   DateAdd("s", 1148499222, "01/01/1970 00:00:00")

outputs:
foo2: (d) = 5/24/2006 7:33:42 PM

which is the date that those numbers should represent if the math/assignment is done correctly.

Is there a function/method to change an array of "unsigned char" values to a "long in network order"? Because that is what the perl pack/unpack does, and I just don't think that I know how to transform the values correctly in VB.

(in reply to bofaboy)
 
 
Post #: 3
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 2:51:04 AM   
  bofaboy

 

Posts: 16
Score: 0
Joined: 12/9/2006
Status: offline
p.s.  the difference in dates being off 7 hours is due to my local time zone (Arizona is -0700 no DST)..  I would eventually need to modify the code to account for time zone and DST..  but that's not an issue..  I can totally do that.

(in reply to bofaboy)
 
 
Post #: 4
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 3:35:11 AM   
  TNO


Posts: 1397
Score: 16
Joined: 12/18/2004
From: thenewobjective.com
Status: offline
could you explain what pack/unpack is in Perl? What does it do? I'm sure we can get an equivalent

_____________________________

To iterate is human, to recurse divine. -- L. Peter Deutsch

(in reply to bofaboy)
 
 
Post #: 5
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 3:45:00 AM   
  bofaboy

 

Posts: 16
Score: 0
Joined: 12/9/2006
Status: offline
sure:

Basically it takes the array of unsigned chars (denoted by the C8 -- 8 unsigned chars), and coreces it to a binary structure..  then the unpack takes that binary structure and converts it to a "long in network order" denoted by the "N".   I hope that this excerpt helps..  I'm not sure of exactly what it does beyond that explanation (and the following excerpt)

excerpt from:

http://www.cs.cmu.edu/People/rgs/pl-exp-conv.html


pack(TEMPLATE,LIST)
Takes an array or list of values and packs it into a binary structure, returning the string containing the structure. The TEMPLATE is a sequence of characters that give the order and type of values, as follows: A An ascii string, will be space padded.
a An ascii string, will be null padded.
c A signed char value.
C An unsigned char value.
s A signed short value.
S An unsigned short value.
i A signed integer value.
I An unsigned integer value.
l A signed long value.
L An unsigned long value.
n A short in "network" order.
N A long in "network" order.
f A single-precision float in the native format.
d A double-precision float in the native format.
p A pointer to a string.
v A short in "VAX" (little-endian) order.
V A long in "VAX" (little-endian) order.
x A null byte.
X Back up a byte.
@ Null fill to absolute position.
u A uuencoded string.
b A bit string (ascending bit order, like vec()).
B A bit string (descending bit order).
h A hex string (low nybble first).
H A hex string (high nybble first).
Each letter may optionally be followed by a number which gives a repeat count. With all types except "a", "A", "b", "B", "h" and "H", the pack function will gobble up that many values from the LIST. A * for the repeat count means to use however many items are left. The "a" and "A" types gobble just one value, but pack it as a string of length count, padding with nulls or spaces as necessary. (When unpacking, "A" strips trailing spaces and nulls, but "a" does not.) Likewise, the "b" and "B" fields pack a string that many bits long. The "h" and "H" fields pack a string that many nybbles long. Real numbers (floats and doubles) are in the native machine format only; due to the multiplicity of floating formats around, and the lack of a standard "network" representation, no facility for interchange has been made. This means that packed floating point data written on one machine may not be readable on another - even if both use IEEE floating point arithmetic (as the endian-ness of the memory representation is not part of the IEEE spec). Note that perl uses doubles internally for all numeric calculation, and converting from double -> float -> double will lose precision (i.e. unpack("f", pack("f", $foo)) will not in general equal $foo).
Examples:
$foo = pack("cccc",65,66,67,68);
# foo eq "ABCD"
$foo = pack("c4",65,66,67,68);
# same thing

$foo = pack("ccxxcc",65,66,67,68);
# foo eq "AB\0\0CD"

$foo = pack("s2",1,2);
# "\1\0\2\0" on little-endian
# "\0\1\0\2" on big-endian

$foo = pack("a4","abcd","x","y","z");
# "abcd"

$foo = pack("aaaa","abcd","x","y","z");
# "axyz"

$foo = pack("a14","abcdefg");
# "abcdefg\0\0\0\0\0\0\0"

$foo = pack("i9pl", gmtime);
# a real struct tm (on my system anyway)

sub bintodec {
unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}The same template may generally also be used in the unpack function.

unpack(TEMPLATE,EXPR)
Unpack does the reverse of pack: it takes a string representing a structure and expands it out into an array value, returning the array value. (In a scalar context, it merely returns the first value produced.) The TEMPLATE has the same format as in the pack function. Here's a subroutine that does substring: sub substr {
local($what,$where,$howmuch) = @_;
unpack("x$where a$howmuch", $what);
}

and then there's

sub ord { unpack("c",$_[0]); }
In addition, you may prefix a field with a %<number> to indicate that you want a <number>-bit checksum of the items instead of the items themselves. Default is a 16-bit checksum. For example, the following computes the same number as the System V sum program: while (<>) {
$checksum += unpack("%16C*", $_);
}
$checksum %= 65536;

(in reply to bofaboy)
 
 
Post #: 6
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 5:05:21 AM   
  TNO


Posts: 1397
Score: 16
Joined: 12/18/2004
From: thenewobjective.com
Status: offline
The quick answer is that vbscript has nothing close to pack and unpack......and doesn't handle binary arrays very easily

this will take a bit of time to figure out a workaround.

_____________________________

To iterate is human, to recurse divine. -- L. Peter Deutsch

(in reply to bofaboy)
 
 
Post #: 7
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 5:35:21 AM   
  TNO


Posts: 1397
Score: 16
Joined: 12/18/2004
From: thenewobjective.com
Status: offline
What do each of these fields represent? Maybe there is a way to avoid using an activeX control

68,116,53,22,0,0,17,36

_____________________________

To iterate is human, to recurse divine. -- L. Peter Deutsch

(in reply to TNO)
 
 
Post #: 8
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 7:07:29 AM   
  bofaboy

 

Posts: 16
Score: 0
Joined: 12/9/2006
Status: offline
if there's an ActiveX control that will help, I'd love to work with it.

That is, if by ActiveX control, you mean COM object -- I think that we're speaking the same language here!?  I've worked with a lot of COM objects in VBScript and perl -- if you can point me in the right direction, I could play with it as well.

The numbers purely are a byte array that together, convert to seconds since epoch..  (00:00:00 1/1/1970)..

In the byte form, they represent nothing.  The application that creates this file, successfully converts the data to time after reading the log file, and I want to as well, so I can take the data and store it in a SQL Server, along with Windows Server Eventlogs (that I already capture) so that I can look at the errors/warnings from the application as well while verifying the Eventlogs daily from multiple servers, and acknowledge warnings/errors in a single source.  It would be a great help to my company to get this information for all the sites that manage this application (~10 sites).

The log file I am parsing doesn't have CRLF line endings for each log entry, and I've been relegated to parsing 188-byte null padded lines of data to extract the various data components (so, I started looking at the data as numbers, so I could see the NULLS (0s)... and try to extrapolate the data from it -- from there I noticed that the only place that was left to look at for the date was position 5-12 in the 188-byte line, so I started playing with the data and found a perl solution that correctly identified the date that the application showed for that log entry...  I tested it on a few other date entries as well, and claimed success..  Only then to realize getting the same stuff to work in VB was the bigger task.  I'd love to just do it in perl, but I can't as the other sites have no expertise in perl and if I die, or get hit by the proverbial bus, no one can support my application.... and well, management likes VBScript.

I can PM you a test log file if you want to see it in action..  but it's an undocumented log file, and there's no programmatic access to dump it to a text file from the application, so I'm parsing ASCII and non-ASCII data out of it.

I originally gave you the short version of the problem I am encountering, because I thought where the data came from was trivial..  They store the date as 8 of the 188-bytes in each line of the log file.

this section is where I was getting the numbers from..  ignore how I currently store it..  it's a placeholder for when I get the originally posted script to work correctly.
  if x >= 5 and x <= 12 Then
    DateStr = DateStr &  character
  End If

here's the full code for pulllogfile.vbs...

Const forReading = 1
Const adTypeText = 2
Const adTypeBinary = 1

log_file = "c:\temp\\logfile.txt"
'open files

'Create Stream object
Set objStream = CreateObject("ADODB.Stream")

'Open the stream And write text/string data To the object
objStream.CharSet = "US-ASCII"
objStream.Type = adTypeText
objStream.Open
objStream.LoadFromFile log_file

x = 0 'x is your position in the 188-byte line
y = 0 'y is your log entry line number
z = 0 'z is your counter to determine if you're finished based on number of bytes being less than the size of the file.
do while z < objStream.Size
x = x + 1
character = objStream.ReadText(1)
if y > 0 Then
  'ignore the first line
  FullStr = FullStr & "-" & Asc(character)
  if x >= 5 and x <= 12 Then
    DateStr = DateStr &  character
  End If
  if x >= 13 and x <= 44 Then
    if Asc(character) >= 32 and Asc(character) < 128 Then
      Source = Source &  character
    End If
  End If
  if x >= 45 and x <=77  Then
    if Asc(character) >= 32 and Asc(character) < 128 Then
      Typ = Typ & character
    End If
  End If
  if x = 80  Then
    if Asc(character) = 1 Then
      SuccessFailure = "Success"
    ElseIf Asc(character) = 0 Then
      SuccessFailure = "Warning"
    ElseIf Asc(character) = 2 Then
      SuccessFailure = "Failure"
    End If
  End If
  if x >= 89 and x <=108  Then
    if Asc(character) >= 32 and Asc(character) < 128 Then
      Area = Area & character
    End If
  End If
  if x >= 109 and x <=187  Then
    if Asc(character) >= 32 and Asc(character) < 128 Then
      Message = Message & character
    End If
  End If
End If
z = z + 1
if x = 187 Then
  y = y + 1
  x = 0
  WScript.Echo UDate(CInt(DateStr)) & " -- " & SuccessFailure & " -- " & Source & " -- " & Typ & " --  " & Area & " --  " & Message
  WScript.Echo
  WScript.Echo FullStr
  FullStr = ""
  TimeStr = ""
  Source = ""
  Status = ""
  Typ = ""
  DateStr = ""
  Area = ""
  Message = ""
End If
Loop

function UDate(intTimeStamp)
UDate = DateAdd("s", intTimeStamp, "01/01/1970 00:00:00")
end function

< Message edited by bofaboy -- 12/11/2006 5:27:14 AM >

(in reply to bofaboy)
 
 
Post #: 9
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 7:32:58 AM   
  TNO


Posts: 1397
Score: 16
Joined: 12/18/2004
From: thenewobjective.com
Status: offline
Yep, ActiveX <---> COM.

There are a few nasty workarounds to would work with the data, but its looks to be around a good 60 lines of code and pretty complex in comparison to PERL in this regard.

Maybe one of my colleagues here know of a way to manipulate the bytearray using an inherent COM API, but until that time I'll keep up the search.

One thng I do know is that .NET has a method of handling bytearrays easily......And I'm 80% certain that using a PowerShell script you could indirectly access it, as for using it.....not quite sure at this point

_____________________________

To iterate is human, to recurse divine. -- L. Peter Deutsch

(in reply to bofaboy)
 
 
Post #: 10
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 7:36:06 AM   
  TNO


Posts: 1397
Score: 16
Joined: 12/18/2004
From: thenewobjective.com
Status: offline
Heres a link to a component that may help:

http://www.voodoofiles.com/20765/ActiveX_ByteArray_object_for_ASP/Net.html


not too sure of its legitimacy though

_____________________________

To iterate is human, to recurse divine. -- L. Peter Deutsch

(in reply to TNO)
 
 
Post #: 11
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 8:54:57 AM   
  ehvbs

 

Posts: 2222
Score: 50
Joined: 6/22/2005
From: Germany
Status: online
I'd try to start with


      

and than tackle 8 bytes, dates, and time zones.

(in reply to TNO)
 
 
Post #: 12
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 2:35:00 PM   
  bofaboy

 

Posts: 16
Score: 0
Joined: 12/9/2006
Status: offline
I'm missing how this is related..  Maybe you could nudge me a little harder.

Are you suggesting that I determine if the value is a Long before I convert it?  It's clearly a Double.

but I only want part of the data returned.

Thanks

(in reply to ehvbs)
 
 
Post #: 13
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 4:31:13 PM   
  TNO


Posts: 1397
Score: 16
Joined: 12/18/2004
From: thenewobjective.com
Status: offline
Since vbscript is defined to store its numbers as
8-byte IEEE floating-point types, it looks like ehvbs is trying to use base 256....That gives me an idea

_____________________________

To iterate is human, to recurse divine. -- L. Peter Deutsch

(in reply to bofaboy)
 
 
Post #: 14
 
 RE: How do I? byte array converted to long, to date... - 12/10/2006 7:31:34 PM   
  TNO


Posts: 1397
Score: 16
Joined: 12/18/2004
From: thenewobjective.com
Status: offline
68,116,53,22,0,0,17,36

I this data what is in the Log file? Or is this after it was converted from what it was? If so, what does the raw data line look like. (The more I look into this, the more unlikely it is that vbscript can do it. Javascript can barely do it by using bit-shifting and modulus division, but its befuddling my brain doing it)

_____________________________

To iterate is human, to recurse divine. -- L. Peter Deutsch

(in reply to TNO)
 
 
Post #: 15
 
 RE: How do I? byte array converted to long, to date... - 12/11/2006 1:57:27 AM   
  bofaboy

 

Posts: 16
Score: 0
Joined: 12/9/2006
Status: offline
the numbers are ascii character codes of the data in the file... so, it's extremely easy to convert between the two...  letters or numbers.

Thanks for all your help.

I'll PM you the file...

(in reply to TNO)
 
 
Post #: 16
 
 RE: How do I? byte array converted to long, to date... - 12/11/2006 5:29:39 AM   
  TNO


Posts: 1397
Score: 16
Joined: 12/18/2004
From: thenewobjective.com
Status: offline
I'm gonna have to use one of my life lines Regis....maybe my fellow moderators would lend a hand on this one.

So if I'm understanding this right, this is what is happening?

68,116,53,22,0,0,17,36   <----Is this a Byte Array or ASCII Array? Means nothing by itself... (8 bytes?)

$foo = pack("c8",68,116,53,22,0,0,17,36)  <----What does $foo equal now? It should be a string of binary correct?

$foo2 = unpack("N",$foo);  <---Convert the binary string into a number (32 bit? 16 bit?)

$foo2 should now equal 1148466454 base 10?

_____________________________

To iterate is human, to recurse divine. -- L. Peter Deutsch

(in reply to bofaboy)
 
 
Post #: 17
 
 RE: How do I? byte array converted to long, to date... - 12/11/2006 5:31:49 AM   
  ebgreen


Posts: 5246
Score: 31
Joined: 7/12/2005
Status: online
I'll play with it for a bit.

_____________________________

"... when you are good and crazy, oooh, oooh, oooh, the sky is the limit!" - The Tick
Goog places to start:http://www.visualbasicscript.com/m_24727/tm.htm
http://www.visualbasicscript.com/m_47117/tm.htm

(in reply to TNO)
 
 
Post #: 18
 
 RE: How do I? byte array converted to long, to date... - 12/11/2006 5:33:49 AM   
  ebgreen


Posts: 5246
Score: 31
Joined: 7/12/2005
Status: online
"the numbers are ascii character codes of the data in the file... so, it's extremely easy to convert between the two...  letters or numbers."

0 does not correspond to any valid char in ASCII.

_____________________________

"... when you are good and crazy, oooh, oooh, oooh, the sky is the limit!" - The Tick
Goog places to start:http://www.visualbasicscript.com/m_24727/tm.htm
http://www.visualbasicscript.com/m_47117/tm.htm

(in reply to ebgreen)
 
 
Post #: 19
 
 RE: How do I? byte array converted to long, to date... - 12/11/2006 5:37:46 AM   
  ebgreen


Posts: 5246
Score: 31
Joined: 7/12/2005
Status: online
Perl's Pack()/UNpack() with a "N" parameter indicates a Big Endian Long.

_____________________________

"... when you are good and crazy, oooh, oooh, oooh, the sky is the limit!" - The Tick
Goog places to start:http://www.visualbasicscript.com/m_24727/tm.htm
http://www.visualbasicscript.com/m_47117/tm.htm

(in reply to ebgreen)
 
 
Post #: 20
 
 
Page:   [1] 2 3   next >   >>
 
  

If you found our site useful please link to us <a href="http://www.visualbasicscript.com">VisualBasicScript.com</a>.
All Forums >> [Scripting] >> WSH & Client Side VBScript >> How do I? byte array converted to long, to date... Page: [1] 2 3   next >   >>
Jump to:





New Messages No New Messages
Hot Topic w/ New Messages Hot Topic w/o New Messages
Locked w/ New Messages Locked w/o New Messages
 Post New Thread
 Reply to Message
 Post New Poll
 Submit Vote
 Delete My Own Post
 Delete My Own Thread
 Rate Posts