在VBScript中将十六进制字符串(图像)转换为base64(用于浏览器呈现)

时间:2013-01-24 15:57:25

标签: vbscript

我有一个输出.bmp验证码图像的脚本。

图像以十六进制构建,并转换为二进制并通过response.binaryWrite chrB(CByte(myHexImage))发送到浏览器(作为图像mime type = bmp)

我想要选择远离它(改变mime类型等),然后向输出发送一些内容,如下所示:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2 ...

(除了我的图像是BMP)

有没有一种快速简便的方法可以在vbscript中将十六进制或二进制转换为base64?这是我现在所描述的内容的片段,如上所述。

如何更改此设置,以便将有效的十六进制格式(我可以轻松转换为base64)或base64直接输出到屏幕上?

    Dim sBmpEndLine, sBmpInfoHeader, sBmpHeader, sTmpHex

    If (m_iBmpWidth Mod 4) <> 0 Then
        sBmpEndLine = string((4 - (m_iBmpWidth Mod 4)) * 2, "0")
    Else
        sBmpEndLine = vbNullString
    End If

    sBmpInfoHeader = array("28000000", "00000000", "00000000", "0100", "0800", "00000000", "00000000", "120B0000", "120B0000", "00000000", "00000000")
    sBmpInfoHeader(1) = formatHex(hex(m_iBmpWidth), 4, 0, True)
    sBmpInfoHeader(2) = formatHex(hex(m_iBmpHeight), 4, 0, True)
    sBmpInfoHeader(6) = formatHex(hex((m_iBmpHeight * m_iBmpWidth) + (m_iBmpHeight * (len(sBmpEndLine) / 2))), 4, 0, True)
    sBmpInfoHeader(9) = formatHex(hex(len(m_sBmpColorMap) / 8), 4, 0, True)
    sBmpInfoHeader(10) = sBmpInfoHeader(9)
    sBmpHeader = array("424D", "00000000", "0000", "0000", "00000000")
    sBmpHeader(1) = formatHex(hex((len(join(sBmpHeader, "")) / 2) + (len(join(sBmpInfoHeader, "")) / 2) + (len(m_sBmpColorMap) / 2) + (m_iBmpHeight * m_iBmpWidth) + (m_iBmpHeight * (len(sBmpEndLine) / 2))), 4, 0, True)
    sBmpHeader(4) = formatHex(hex((len(join(sBmpHeader, "")) / 2) + (len(join(sBmpInfoHeader, "")) / 2) + (len(m_sBmpColorMap) / 2)), 4, 0, True)

    sendHex(join(sBmpHeader, ""))
    sendHex(join(sBmpInfoHeader, ""))
    sendHex(m_sBmpColorMap)
    For y = m_iBmpHeight To 1 Step -1
        For x = 1 To m_iBmpWidth
            sTmpHex = m_aBitmap(y, x)
            If sTmpHex = vbNullString Then
                sendHex(m_sBgColor)
            Else
                sendHex(sTmpHex)
            End If
        Next
        sendHex(sBmpEndLine)
    Next

    Response.Flush

这是sendHex()函数:

Private Sub sendHex(valHex)

    Dim iCntHex
    For iCntHex = 1 To len(valHex) Step 2
        'Response.BinaryWrite chrB(CByte("&H" & mid(valHex, iCntHex, 2)))
        response.Write "&H" & mid(valHex, iCntHex, 2)
    Next
End Sub

2 个答案:

答案 0 :(得分:1)

Microsoft.XMLDOM内置了bin.base64bin.hex转换器。我编写的函数演示了如何使用它:

Function TextToBinary(text, dataType)
  Dim dom
  Set dom = CreateObject("Microsoft.XMLDOM")
  dom.loadXML("<HELLO/>")
  dom.documentElement.nodeTypedValue = text
  dom.documentElement.dataType = dataType
  TextToBinary = dom.documentElement.nodeTypedValue
End Function

Function BinaryToText(binary, dataType)
  Dim dom
  Set dom = CreateObject("Microsoft.XMLDOM")
  dom.loadXML("<HELLO/>")
  dom.documentElement.dataType = dataType
  dom.documentElement.nodeTypedValue = binary
  dom.documentElement.removeAttribute("dt:dt")
  BinaryToText = dom.documentElement.nodeTypedValue
End Function

Function HexToBase64(strHex)
  HexToBase64 = BinaryToText(TextToBinary(strHex, "bin.hex"), "bin.base64")
End Function

Function Base64ToHex(strBase64)
  Base64ToHex = BinaryToText(TextToBinary(strBase64, "bin.base64"), "bin.hex")
End Function

以下是其用法示例:

MsgBox HexToBase64("41")
MsgBox Base64ToHex("QQ==")

另请参阅ADODB.Stream作为处理二进制文件的方法。它将适用于这些例程。

答案 1 :(得分:0)

我能够让这个工作。这是如何。

在sendHex中,我删除了&H部分,并将我的字符串包裹在hex()中:

Private Sub sendHex(valHex)
    Dim iCntHex
    For iCntHex = 1 To len(valHex) Step 2
    If len( mid(valHex, iCntHex, 2)) = 1 Then 
        response.write "0"
    end if 
    response.write mid(valHex, iCntHex, 2)
    Next
End Sub

这会导致像这样的字符串输出(在2个十六进制字符的字节字符串中):

424d1e050000000000003e00000028000000340000001800000001000

然后我可以将正确的十六进制字符串转储到HEXbase64函数中,如下所示(不是由我写的,而是由Richard Mueller写的 - http://www.rlmueller.net/Base64.htm

Function HexToBase64(strHex)
    ' Function to convert a hex string into a base64 encoded string.
    ' Constant B64 has global scope.
    Dim lngValue, lngTemp, lngChar, intLen, k, j, strWord, str64, intTerm

    intLen = Len(strHex)

    ' Pad with zeros to multiple of 3 bytes.
    intTerm = intLen Mod 6
    If (intTerm = 4) Then
        strHex = strHex & "00"
        intLen = intLen + 2
    End If
    If (intTerm = 2) Then
        strHex = strHex & "0000"
        intLen = intLen + 4
    End If

    ' Parse into groups of 3 hex bytes.
    j = 0
    strWord = ""
    HexToBase64 = ""
    For k = 1 To intLen Step 2
        j = j + 1
        strWord = strWord & Mid(strHex, k, 2)
        If (j = 3) Then
            ' Convert 3 8-bit bytes into 4 6-bit characters.
            lngValue = CCur("&H" & strWord)

            lngTemp = Fix(lngValue / 64)
            lngChar = lngValue - (64 * lngTemp)
            str64 = Mid(B64, lngChar + 1, 1)
            lngValue = lngTemp

            lngTemp = Fix(lngValue / 64)
            lngChar = lngValue - (64 * lngTemp)
            str64 = Mid(B64, lngChar + 1, 1) & str64
            lngValue = lngTemp

            lngTemp = Fix(lngValue / 64)
            lngChar = lngValue - (64 * lngTemp)
            str64 = Mid(B64, lngChar + 1, 1) & str64

            str64 = Mid(B64, lngTemp + 1, 1) & str64

            HexToBase64 = HexToBase64 & str64
            j = 0
            strWord = ""
        End If
    Next
    ' Account for padding.
    If (intTerm = 4) Then
        HexToBase64 = Left(HexToBase64, Len(HexToBase64) - 1) & "="
    End If
    If (intTerm = 2) Then
        HexToBase64 = Left(HexToBase64, Len(HexToBase64) - 2) & "=="
    End If

End Function

这会将上面的内容转换为base64,我可以像这样使用输出(例如在浏览器网址栏中)将其视为图像:

data:image/bmp;base64,Qk0eBQAAAAAAAD4AAAAo...