深入解析ASP核心技术
上QQ阅读APP看书,第一时间看更新

2.1.5 常用的转换函数

1. 字符与数字的转换

Asc函数返回与字符对应的编码数字,Chr函数则反之,根据编码数字返回与之对应的字符。转换的对应关系如图2-2所示。

图2-2 字符与数字的转换关系图

应该注意到,这两个函数只是改变了数据类型,内存存储并没有发生变化,而且转换双方的内存占用的都是两个字节。

这两个函数概括起来就是一句话:字符就是数字,数字就是字符。

2. 字节与数字的转换

AscB和ChrB函数的作用类似,只是它们的作用范围是字节,而不是字符。转换的对应关系如图2-3所示。

图2-3 字节与数字的转换关系图

AscB函数根据字符的第一个字节返回对应的数字,它返回的是一个Byte类型。ChrB函数是根据数字返回对应字符,但是,它返回的是一个单字节字符,它的数据类型是String,但是只有一个字节。

要注意理解Chr和ChrB两个函数的区别,前者返回一个字符,它是Unicode编码的,总是占用两个字节,后者则返回一个字节。Chr函数的参数是在0~65535之间,而ChrB函数的参数只能在0~255之间。

ChrB函数的参数类型可以是Byte、Integer或者Long,这个对结果没有丝毫影响,因为该函数只使用参数的第一个字节。

这两个函数概括起来说,AscB函数是截取字符串的第一个字节,ChrB函数则将一个字节还原为字符串。主要作用还是转换类型,这一个字节的数据存储本身并没有改变。

3. 其他常见函数

其他一些可能用到的函数就是LeftB、MidB、RightB、LenB、InstrB等一些以字节为单位进行操作的函数,都比较好理解,不再细说。

还有两个函数容易让人困惑,就是AscW和ChrW。其实不难理解,在使用这两个函数进行字符和数字转换时,这个数字始终是指字符的Unicode编码数字,而使用Asc和Chr函数时,数字是指GBK、BIG5或SHIFT_JIS等编码数字,具体是哪个编码,取决于程序控制。

举一个例子,如汉字“啊”字的GBK编码是B0A1, Unicode编码是554A,几个函数的转换结果如表2-4所示。

表2-4 转换举例

Asc和AscW函数可能返回负值,如Asc("啊")返回的就是-20319。很多人都知道处理方法是在这个数字上加上65536,下面就来分析一下为何要这样做。

字符“啊”的GBK编码是B0 A1,即十进制的45217。Asc和AscW函数的返回类型是Integer,它最大只能表示32767。

相关数字的二进制形式如表2-5所示。

表2-5 数字为Integer型时的二进制形式

在Integer数据类型中,最高位的1个比特是用来表示正负的,0表示正数,1表示负数。数字45217的二进制形式最高位是1,这个二进制形式单独说说当然是没问题的,但是当把它作为Integer类型处理时,它就成了-20319。

补救方法就是把数据类型转换为Long型,这两个数字为Long型时的二进制形式如表2-6所示。

表2-6 数字为Long型时的二进制形式

要把Long型的-20319变为45217,其实就是要把左边两个字节的1全变为0。其实,首先想到的应该是“位与”操作,即按位进行与操作。

b = CLng(-20319)
d = b AND &H0000FFFF&
response.write d

前两个字节用0进行与操作,结果一定是0,后两个字节用1进行与操作,结果一定和原数据一致。于是,清晰明了地实现了前两个字节置0的操作。

而给-20319加上65536,其实是有点取巧的方法,在第二个字节的最后一位加上1,结果为0,并向前进位,如此类推,直到最后一个进位溢出,从而实现前两个字节的置0。

还有一种方式,是利用Hex函数,如CLng("&H" & Hex(-20319)),也会得到正确结果。

4. 字节数组与BSTR

在一些编程语言中是有字节数组的这个概念的(如Java中是byte[])。在VBScript中,是无法直接创建字节数组的。各位可能会想,创建一个数组,然后在每个元素中放入一个字节数据不就可以了吗?看一下例子。

Dim x(2)
x(0)=Cbyte(60)
x(1)=cbyte(61)
x(2)=cbyte(62)
response.write typename(x) &"<br>"
response.write vartype(x) &"<br>"

输出的是 Variant()和8204,说明它只是一个变量数组,而非字节数组。真正的字节数组,应该输出为Byte()和8209。

想要创建字节数组,只能依靠一些组件(如Adodb.Stream)的帮助,使用Request. BinaryRead方法所读取的表单数据也是字节数组。

在很多程序中,会使用多个ChrB()拼接,从而得到一个字符串,它的实际内存存储是对应的字节数据,本书将这种字符串称为二进制字符串,简写为BSTR。

一个ChrB()返回的是一个字节的数据,即使输出也是乱七八糟的字符,但是多个ChrB()的字节连起来就不同了。如下面两行代码效果是一样的:

response.write chrB(&H4A) & chrB(&H55&) &"<br>"
response.write "啊" & "<br>"

两个字节的数据连起来,4A 55对应的正是“啊”字。