All Forums >> [Scripting] >> WSH & Client Side VBScript >> RE: 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!
yeah, closest I can get to a solution is a .NET one....and a javascript one for a 4bit byte array...I was trying to avoid using COM components as well if they aren't inherent to the OS. hmm....
_____________________________
To iterate is human, to recurse divine. -- L. Peter Deutsch
I am reading an ADODB Stream as text, therefore all data is returned as text/ascii character codes.
I say ASCII character code values because they are... You are right that 0 doesn't correspond to any printable number, letter, or special (because it's outside the range of 32-127, but it's still ASCII.)
I'd never thought of that... but yes, that would work.
Would the syntax be like classic ASP when you try to mix languages? Yes Windows Activestate perl.
I am familiar with using a "spamsink.vbs" with a "PerlScript" language declaration for some other stuff in Exchange 2000 to load perl's SpamAssassin filter. <SCRIPT LANGUAGE="PerlScript"> blah.... </SCRIPT>
My only problem in doing multi-language WSF was that at work, my employer doesn't do perl.. or at least at the other sites, they don't do perl.. they only like VBS. However, they may not have an option. :)
But it's a simple enough statement that it may never need to be modified, and the only requirement is that it get installed with the PerlScript options.
ok.. so, since we can't do it in VBScript, and we were going to shell out to perl to fix the shortcomings.. any chance someone could help me write a .Net app to do it? I'm thinking that an exe is more palletable than loading perl on 10 servers.
A wsf would be smaller and prettier I think without having to register anything. But I'm not up to speed on perl. Could you write this portion as a stand alone function? in goes the array, out goes the result?
_____________________________
To iterate is human, to recurse divine. -- L. Peter Deutsch
Perl is a 13MB download that expands into 26MB-50MB.
registering anything in .NET would be much less obtrusive. I'm thinking a small 200KB executable file.
The exe I was thinking of would take those 4 numbers as arguments, and return the 1148499222 type of value as an errorlevel or as STDOUT. Something along the lines of this: (this does not work and I am by no means anywhere close to anything except danger when I try to code VB.NET so far, so laugh freely, heartily, and at my expense ).
Module dayssinceepoch Sub Main() Dim arguments As [String]() = Environment.GetCommandLineArgs() Dim arg Dim x Dim asciicodes x = 0 asciicodes = ""
For Each arg In arguments If x > 0 Then
Console.Write(arg & " ") If x = 1 Then
asciicodes = Chr(arg) Else
asciicodes = asciicodes & Chr(arg) End If
End If
x += 1 Next
Console.WriteLine() Console.WriteLine(asciicodes)
Dim asciibytes As Byte() = Encoding.ASCII.GetBytes(asciicodes)
Dim this = Encoding.Convert(Encoding.ASCII, Encoding.Unicode, asciibytes) Dim this2 = Encoding.Convert(Encoding.Unicode, Encoding.BigEndianUnicode, this)
Another vbscript attempt: If in PERL: $foo = pack("c8",68,116,53,22,0,0,17,36); $foo = Dt5? ?$ Then in vbscript: Dim Foo Foo = Chr(68)&Chr(116)&Chr(53)&Chr(22)&Chr(0)&Chr(0)&Chr(17)&Chr(36)
so now $foo should = Foo right?
So now to convert back into a number..
If in PERL:
$foo2 = unpack("N",$foo); $foo2 = 1148466454
Then in vbscrript all we have to figure out is how to convert Foo into a "Long in Network Order" So what is a "Long in Network Order"? is this a big endian long we are converting to? So we have to convert the binary of Foo into the binary of a bigendian long, then convert that into base 10 for our final value?
Just thinking out loud, maybe someone can take it from here until I come up with a little more...
_____________________________
To iterate is human, to recurse divine. -- L. Peter Deutsch
Pardon me/Just ignore the following, if you feel I'm pushy. Please give me a hint if I misunderstood this problem.
But I'm interested in the problem (as I see it) and I think:
(a) after bofaboy's "my employer doesn't do perl" using Perl for production code can be rated as fallback/'if all else fails' solution only
(b) after bofaboy's "I am only using the first 4" the problem of fighting 64 bit long integers is out of the way
(c) bofaboy's "we can't do it in VBScript" can't be true. VBScript may be more like an Scooter compared to Porsches with king size trunks like Perl or flying trucks like .NET, but multiplying the elements of an array with suitable choosen powers of 256 ... Come on, that may need some work to get the byte order right and to avoid overflow, but you don't need .NET for that.
There may be BAD errors and UGLY inefficiencies in:
Function convA4Dbl( a4 ) Dim aBVals : aBVals = Array( 256 ^ 3, 256 ^ 2, 256 ^ 1, 256 ^ 0 ) Dim dblRVal : dblRVal = 0.0 Dim nIdx For nIdx = 0 To UBound( aBVals ) dblRVal = dblRVal + (aBVals( nIdx ) * a4( nIdx ) ) Next convA4Dbl = dblRVal End Function
but working together we should be able to improve it to production quality in a short time - if you feel like it, of course.
(d) I wrote a small script to test convA4Dbl(); in contrast to my first posting, the relation to the original posting is more explicit and other as my last one it's pure VBScript:
It still lacks explanations, but I believe I'm writing to experts here, who can/would ask questions without hesitation.
(d) What really worries me: AFAIK, the VBScript date functionality is based on local time. Adding a certain number of seconds to dtFrsDate = DateSerial( 1970, 1, 1 ) + TimeSerial( 0, 0, 0 ) on different computers in different time zones could lead to slightly (?) different results. Please, bofaboy, tell me that you/your employers don't care. I would hate to take back my "no (big) problem to do it in VBScript"!
I will look at the functions you provided just now, and see if I can make it work.
I am only using .NET as a fallback, and don't want to do any part of it in perl as it would require a download on each server that needs this (~10+).. that isn't going to fly with my boss.
My estimation that VBScript won't do it, is a culmination of feelings when seeing what the group here has been trying to get done, but having a hard time doing.. Please take no offense here, but there are others telling me that it can't be done in VBScript (due to the nature of the pack/unpack missing in VBscript problem).
If there is a solution, I'd love it. I don't want to have to depend on outside executables to make this happen and only consider it a last resort step, as people are telling me that .NET can totally do it.
I think I have a few hours today to look at this.. (in about 40 minutes when I get to work and get settled). :)
HOLY MACKERAL AND THANK YOU!! Just an FYI... the problem with the numbers being slightly off is the application trying to be tricky...
I pared down your code and slightly modified it. The application doesn't return seconds since 1970, but seconds since 1970 and 32768 seconds.. As well, I added the time zone conversions via WMI.. it will need to be slightly modified to get timezone from the server, but, needless to say, that's easy enough to change..
THANK YOU THANK YOU THANK YOU... when you first posted this solution a few days ago, I didn't understand it.. thanks for sticking with me and clarifying... I'll test it more throughout the day just to make sure, but with your help, I think we've claimed success. Again, Thank you!
slightly modified code output:
offset (seconds): -25200 ehvbs and offset: 1148474031 ehvbs: 1148499231 date with offset: 5/24/2006 12:33:51 PM
slightly modified code:
Option Explicit On Error Resume Next Dim offset_sec,rtn rtn = get_time_zone_offset (offset_sec) WScript.Echo "offset (seconds): " & offset_sec
Function get_time_zone_offset(time_zone_minutes) Dim wmiobj,tz,tzitem Set wmiobj = GetObject("winmgmts:\\.") if Err.Number <> 0 Then WScript.Echo "error creating timezone wmi object" get_time_zone_offset = 0 Exit Function End If Set tz = wmiobj.ExecQuery("select Bias from Win32_TimeZone") if Err.Number <> 0 Then WScript.Echo "error getting currently set Bias from wmi object" get_time_zone_offset = 0 Exit Function End If for each tzitem in tz time_zone_minutes = tzitem.Bias * 60 get_time_zone_offset = 1 Exit Function Next get_time_zone_offset = 0 End Function
Function convA4Dbl( a4 ) Dim aBVals : aBVals = Array( 256 ^ 3, 256 ^ 2, 256 ^ 1, 256 ^ 0 ) Dim dblRVal : dblRVal = 0.0 Dim nIdx For nIdx = 0 To UBound( aBVals ) dblRVal = dblRVal + (aBVals( nIdx ) * a4( nIdx ) ) Next convA4Dbl = dblRVal + 32768 End Function
Your are very welcome, bofaboy. You made me happy by your kind words and by extenting my code with the time zone stuff. I'l study it carefully and will use it to improve some of my scripts. In addition to that: getting further/independent testing for concepts/code is always a boon.
Thank you for this gratifying piece of cooperative work!
ehvbs
My output:
cscript convba-01.vbs offset (seconds): 3600 <--- I like that! ehvbs and offset: 1148502831 ehvbs: 1148499231 date with offset: 24.05.2006 20:33:51
< Message edited by ehvbs -- 12/12/2006 3:21:45 AM >