网络开发人员必须为用户提供容易使用的操作方式,而且也要从保护公司的知识产权的角度来考虑。为了避免公司商业秘密泄露到其它竞争对手,你必须寻找一种用户容易使用而竞争对手很难或者根本不可能开发的方法。这一方法可以通过使用图像和语音字节而建立用于登录密码(passcode)来实现。
WHOIS data on Network Solutions' site(Network Solutions网站的WHOIS数据)为知识产权的一个例子。如果用户对使用有关一个特定域的注册信息感兴趣,Network Solutions就为用户提供一种搜索WHOIS数据库的方法。然而另一方面,这些信息成为其它竞争对手注意的一个知识仓库。
Network Solutions已经采取一系列措施以保护自己和用户。这一公司已开发一个完整的体系以具有削弱竞争者而保护自己的实力。这一体系包括一个代表用户的密码,这一密码是以图像为形式,其包含足够的背景混淆信息以防范一些光学符号识别(OCR)的验证。当前,使用密码来建立OCR仿伪图像的系统很流行,所以无需考虑开发这一功能的费用。然而,这一系统也还有一些缺陷。
如果你检查Network Solutions的WHOIS搜索工具,你将会注意到,视力不太好的用户可以使用一个指向电话号码的链接,而这一链接可以使得网站被访问,但网站不能为用户提供各种服务。另一方法是,网站为视力不好的用户提供了一种可以聆听密码的方法,这样他们就可以进入到想进入的网页。通过指定浏览器连接到具有语音字节传输的Web网页或者CGI脚本,你可以实现这一功能。语音字节文件的格式将影响每个用户的语音字节的传递过程。
我使用的是微软的PCM WAV文件格式。你可以在这里找到这一格式的详细规范。由于这一独立语音字节的格式是连贯的,所以我唯一需要做的就是在头文件中调整文件的尺寸,并将原始数据添加到现存的数据中。一旦我改变了响应的MIME字节并发送数据,用户将听到密码的语音代号。
绝大多数的程序开发和脚本语言都包含文件I/O操作。对于现在的情况,我将建立一个Visual Basic的COM组件。这一组件获得一个文件字符串的数组,并返回语音字节的二进制流。以下是这一过程的代码:
'Class Module
Option Explicit
Option Base 0
Dim fso As Scripting.FileSystemObject
Dim f As Scripting.File
Dim adoStream As ADODB.Stream
Public Type FILESTRUCT
ChunkID(3) As Byte
ChunkSize(3) As Byte
Format(3) As Byte
Subchunk1ID(3) As Byte
Subchunk1Size(3) As Byte
AudioFormat(1) As Byte
NumChannels(1) As Byte
SampleRate(3) As Byte
ByteRate(3) As Byte
BlockAlign(1) As Byte
BitsPerSample(1) As Byte
Subchunk2ID(3) As Byte
Subchunk2Size(3) As Byte
Data() As Byte
End Type
Dim ChunkID, FileFormat, Subchunk1ID, AudioFormat, Stereo, Mono, _
SampleRate, BitsPerSample, Subchunk2ID
Public Function StitchFiles(sFiles As Variant) As ADODB.Stream
Dim iFile As Integer
Dim fsFiles() As FILESTRUCT
Dim fsFile As FILESTRUCT
Dim lFileSize As Long, lOffset As Long
Dim adoStream As ADODB.Stream
Dim bData() As Byte
ReDimfsFiles(UBound(sFiles)) As FILESTRUCT
lFileSize = 0
lOffset = 0
For iFile = LBound(sFiles) To UBound(sFiles)
Dim lSize As Long
fsFiles(iFile) = SetFile(sFiles(iFile))
lSize = CalcLittleEndianValue(fsFiles(iFile).Subchunk2Size)
lFileSize = lFileSize + lSize
ReDim Preserve bData(lFileSize
- 1) As Byte
CopyByteArraybData, fsFiles(iFile).Data,
lSize, lOffset
lOffset = lOffset + lSize
Next
CopyByteArrayfsFile.ChunkID, ChunkID, 4
CopyByteArrayfsFile.ChunkSize, GetLittleEndianByteArray(36
+ lFileSize), 4
CopyByteArrayfsFile.Format, FileFormat, 4
CopyByteArray fsFile.Subchunk1ID, Subchunk1ID, 4
CopyByteArray fsFile.Subchunk1Size, Array(&H10,
&H0, &H0, &H0), 4
CopyByteArrayfsFile.AudioFormat, AudioFormat, 2
CopyByteArrayfsFile.NumChannels, Stereo, 2
CopyByteArrayfsFile.SampleRate, SampleRate, 4
CopyByteArrayfsFile.ByteRate, GetLittleEndianByteArray(
_
CalcLittleEndianValue(SampleRate)
* _
CalcLittleEndianValue(Stereo) * _
(CalcLittleEndianValue(BitsPerSample) /
8)), 4
CopyByteArrayfsFile.BlockAlign, GetLittleEndianByteArray(CalcLittleEndianValue(Stereo)
* _
(CalcLittleEndianValue(BitsPerSample) / 8)), 2
CopyByteArrayfsFile.BitsPerSample, BitsPerSample,
2
CopyByteArray fsFile.Subchunk2ID, Subchunk2ID, 4
CopyByteArray fsFile.Subchunk2Size, GetLittleEndianByteArray(lFileSize),
4
Dim fsba() As Byte
ReDimfsba(Len(fsFile) - 5) As Byte
CopyMemoryfsba(0), fsFile, Len(fsFile) - 4
Set adoStream = New ADODB.Stream
adoStream.Type = adTypeBinary
adoStream.Mode = adModeReadWrite
adoStream.Open 'fsFile
adoStream.Writefsba
adoStream.WritebData
Set StitchFiles = adoStream
Set adoStream = Nothing
End Function
Private Function SetFile(sFileName) As FILESTRUCT
Dim fsFile As FILESTRUCT
If fso.FileExists(sFileName) Then
Dim iAvail As Integer
iAvail = FreeFile()
Open sFileName For Binary
Access Read As #iAvail
Get #iAvail, , fsFile.ChunkID
Get #iAvail, , fsFile.ChunkSize
Get #iAvail, , fsFile.Format
Get #iAvail, , fsFile.Subchunk1ID
Get #iAvail, , fsFile.Subchunk1Size
Get #iAvail, , fsFile.AudioFormat
Get #iAvail, , fsFile.NumChannels
Get #iAvail, , fsFile.SampleRate
Get #iAvail, , fsFile.ByteRate
Get #iAvail, , fsFile.BlockAlign
Get #iAvail, , fsFile.BitsPerSample
Get #iAvail, , fsFile.Subchunk2ID
Get #iAvail, , fsFile.Subchunk2Size
Dim lSize As Long
lSize = CalcLittleEndianValue(fsFile.Subchunk2Size)
ReDimfsFile.Data(lSize - 1)
As Byte
Get #iAvail, , fsFile.Data
Close #iAvail
End If
SetFile = fsFile
End Function
Private Function CalcLittleEndianValue(bValue As Variant)
Dim iByte As Integer, lSize As Long
For iByte = LBound(bValue) To UBound(bValue)
lSize = lSize + (bValue(iByte)
* (16 ^ (iByte * 2)))
Next
CalcLittleEndianValue = lSize
End Function
Private Function GetLittleEndianByteArray(lValue) As Byte()
Dim running As Double
Dim b(3) As Byte
running = lValue / (16 ^ 6)
b(3) = Int(running)
running = running - b(3)
running = running * 256
b(2) = Int(running)
running = running - b(2)
running = running * 256
b(1) = Int(running)
running = running - b(1)
running = running * 256
b(0) = Round(running)
GetLittleEndianByteArray = b
End Function
Private Sub CopyByteArray(bDest As Variant, bSource As Variant, lLength As
Long, Optional lOffset As
Long = 0)
Dim l As Long
For l = 0 To (lLength - 1)
If lOffset > 0 Then
bDest(l
+ lOffset) = bSource(l)
Else
bDest(l)
= bSource(l)
End If
Next
End Sub