Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Binary objects, String representations 1

Status
Not open for further replies.

shadedecho

Programmer
Oct 4, 2002
336
US
OK, I know this may sound like a strange request, but...

Let's say from some location (like an ActiveX object for instance) I'm getting in my JAVASCRIPT a variable that is a binary packed object. This object is guaranteed to be a set of packed bytes, where each byte represents a single printable ascii character, thus the object always has a printable string representation.

If I then pass it to this VBSCRIPT function:

Code:
Function BinaryToString(Binary)
Dim I,S
For I = 1 to LenB(Binary)
S = S & Chr(AscB(MidB(Binary,I,1)))
Next
BinaryToString = S
End Function

The returned value from this VBSCRIPT function will be the printable string representation of the Binary object in question. As far as I understand things, the above function has no such equivalent in Javascript since Javascript won't let me work with an arbitrary object byte by byte (there's no MidB() function in JS). But, the VBSCRIPT function works just as needed.

So, all that is fine. Now, this is what I am trying to accomplish... I want to actually reverse that process. I want to, in some way, with a combination of VBScript and Javascript, be able to create a binary packed object in the same way such that each byte of it represents a printable ascii character from some arbitrary string.

So, basically I want a function like this:

Code:
Function StringToBinary(str)
Dim BinObj
  ...
  StringToBinary = BinObj
End Function

Which returns the binary object representation of that string.

Now, I am aware that VBSCRIPT doesn't have binary shift operators, but Javascript does, so I am thinking perhaps I will need to combine both JS and VBS for a solution.

I was thinking I would have to do things like obj = ((obj<<8)|nextchar) to shift on characters byte by byte into the object. But the mechanics of how to do this are eluding me.

Anyone have any ideas?
 
I don't see any "binary objects" here at all. It sounds more like a character encoding issue, Unicode vs. ANSI.

Why not just use an ADO Stream object to handle these translations?
 
My issue is that I get this particular type of packed binary object ("array" of sorts) from an external source (such as an ActiveX control), and if I pass it to that function I gave, I get a printable string representation of it. But I don't know how to go the other way, to take an arbitrary string of characters and create the same sort of "binary object", without having the ActiveX control create it.

In other words: BinaryToString(StringToBinary("my string")) should return "my string".

From my analysis of the VBscript function (which I didn't write btw, I just found) it appears it is taking single bytes and treating them as characters (which is correct!) and "unpacking" them into their 2-byte character representation in a string.

The real crux of the issue seems to be in how to actually create a densely packed data structure (a "string" of single-byte characters) in javascript or vbscript, as this ActiveX control seems to somehow be able to do. The object in question seems to have no type, no "length", and can't be msgbox'd or alert'd. But, magically, if passed to that above vbscript function, it comes out as the string I want it to.

All the data structures I can create by script seem to be of type variant or something like that, which seems to morph its size and internal byte representations without letting me having control over the single bytes.

Furthermore, from what I can tell, vbscript (and javascript!) seems to represent each character in a string by two bytes, so I don't think that the string data structure will be sufficient to represent this "binary object".

dilettante:
Can you tell me how I would use ADOStream inside of a set of VBScript and/or Javascript in a webpage to be able to take any string value (of 2-byte characters) and "convert" it to this single byte "string" data structure object?
 
[0] You have made serveral observations on vbscript vs jscript which I do not completely agree. But that is not the subject matter and I won't insist.

[1] I believe dilettante can send you simple script for that matter using adodb.stream.

[2] I can send you a function molded to your notations with a more modern flavour. Whether you are ready to receive the construction in its full force, I cannot guarantee as it is not easy to close the round trip in verification you get the proper result as vbs is not immediately ready to manipulate the byte array.
[tt]
function stringtobinary(str)
dim binobj
dim ahex(),oparser,oelem
redim ahex(lenb(str)-1)
for i=0 to lenb(str)-1
ahex(i)=right("00" & hex(ascb(midb(str,i+1,1))),2)
next
set oparser=createobject("msxml2.domdocument")
with oparser
set oelem=.createElement("x")
oelem.datatype="bin.hex"
oelem.text=join(ahex,"")
binobj=oelem.nodetypedvalue
end with
set oelem=nothing
set oparser=nothing
stringtobinary=binobj
end function
[/tt]
[3] Since the internal representation of a string variable is unicode, the result also reflect the fact using lenb(), ascb() and midb().
 
tsuji:

I appreciate your responses.

[0] --> please, help me to understand what assertions I've made about jscript vs vbscript which are inaccurate. I certainly don't claim to fully understand them, only enough to be trying to wade into the mess in the first place. :)

[2] --> when I used your function and called: alert(BinaryToString(stringtobinary("blah"))); from inside of my javascript, I get "b", not the whole string "blah". The same was true if i called: msgbox BinaryToString(binobj) at the end of the function you gave me.

But, I feel this is much closer than I've gotten so far, in that at least i'm getting the first character back correctly. Any idea why ONLY the first character is there?

Were you meaning by the "ready" part that I'd need some sort of delay to let vbscript be ready to pass the full binary data back (and maybe this is why i only get the first character)?
 
[4] The "binary packed object" (which is not very technical precise): I can only take it to mean Byte() (byte array). You can at least verify in vbscript with unbound.
[tt]
s="blah"
a=stringtobinary(s)
wscript.echo ubound(a)
[/tt]
 
Further note

[2.1] I think you mean to work with ascii (8-bit) rather than unicode (internal) representation from the look of your BinaryToString(Binary). In that case, I can modify the function accordingly using len(), asc(), mid() instead.
[tt]
function asciistringtobinary(str)
dim binobj
dim ahex(),oparser,oelem
redim ahex(len(str)-1)
for i=0 to len(str)-1
ahex(i)=right("00" & hex(asc(mid(str,i+1,1))),2)
next
set oparser=createobject("msxml2.domdocument")
with oparser
set oelem=.createElement("x")
oelem.datatype="bin.hex"
oelem.text=join(ahex,"")
binobj=oelem.nodetypedvalue
end with
set oelem=nothing
set oparser=nothing
asciistringtobinary=binobj
end function
[/tt]
[2.1.1] The testing setup would be this.
[tt]
s="blah"
a=asciistringtobinary(s)
wscript.echo ubound(a)
t=binarytostring(a)
wscript.echo t
[/tt]
 
tsuji-
Thanks! That asciistringtobinary was exactly what I was looking for. it works perfectly.
 
It may be somewhat quicker to use a Stream as I suggested earlier:
Code:
Option Explicit

Function StrConv(ByRef Source, ByVal ToString)
  Dim Stream
  Const adTypeBinary = 1
  Const adTypeText = 2

  Set Stream = CreateObject("ADODB.Stream")
  With Stream
    .Open
    If ToString Then
      .Type = adTypeBinary
      .Write Source
      .Position = 0
      .Type = adTypeText
      .Charset = "ascii"
      StrConv = .ReadText()
    Else
      .Type = adTypeText
      .Charset = "ascii"
      .WriteText Source
      .Position = 0
      .Type = adTypeBinary
      StrConv = .Read()
    End If
    .Close
  End with
End Function

Dim S, B

'Start.
S = "ABCDEFGH"
WScript.Echo TypeName(S)

'Convert to ASCII Byte array.
B = StrConv(S, False)
WScript.Echo TypeName(B)

'Convert back to String.
S = StrConv(B, True)
WScript.Echo TypeName(S) & vbNewLine & S
But if you aren't doing a lot of this and the "strings" are fairly short you probably won't notice. You can optimize both examples a bit more by creating the objects outside of the conversion routine once and re-using them.
 
Note that because it has some powerful capabilities you cannot use the ADO Stream object in client-side script in a web page. HTAs are fine, but IE will block creation of the object in an HTML page.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top