用于文件上传VB.Net的Base64编码

时间:2014-12-02 10:52:01

标签: vb.net vba file-upload encoding base64

我在 VBA 中有一个项目,它执行base64编码并上传文件(.xlsm)。

VBA代码:

Option Explicit

Private Const clOneMask = 16515072          '000000 111111 111111 111111
Private Const clTwoMask = 258048            '111111 000000 111111 111111
Private Const clThreeMask = 4032            '111111 111111 000000 111111
Private Const clFourMask = 63               '111111 111111 111111 000000

Private Const clHighMask = 16711680         '11111111 00000000 00000000
Private Const clMidMask = 65280             '00000000 11111111 00000000
Private Const clLowMask = 255               '00000000 00000000 11111111

Private Const cl2Exp18 = 262144             '2 to the 18th power
Private Const cl2Exp12 = 4096               '2 to the 12th
Private Const cl2Exp6 = 64                  '2 to the 6th
Private Const cl2Exp8 = 256                 '2 to the 8th
Private Const cl2Exp16 = 65536              '2 to the 16th

Private cbTransTo(63) As Byte
Private cbTransFrom(255) As Byte
Private clPowers8(255) As Long
Private clPowers16(255) As Long
Private clPowers6(63) As Long
Private clPowers12(63) As Long
Private clPowers18(63) As Long

Private Sub Class_Initialize()

    Dim lTemp As Long

    For lTemp = 0 To 63                             'Fill the translation table.
        Select Case lTemp
            Case 0 To 25
                cbTransTo(lTemp) = 65 + lTemp       'A - Z
            Case 26 To 51
                cbTransTo(lTemp) = 71 + lTemp       'a - z
            Case 52 To 61
                cbTransTo(lTemp) = lTemp - 4        '1 - 0
            Case 62
                cbTransTo(lTemp) = 43               'Chr(43) = "+"
            Case 63
                cbTransTo(lTemp) = 47               'Chr(47) = "/"
        End Select
    Next lTemp

    For lTemp = 0 To 255                            'Fill the lookup tables.
        clPowers8(lTemp) = lTemp * cl2Exp8
        clPowers16(lTemp) = lTemp * cl2Exp16
    Next lTemp

    For lTemp = 0 To 63
        clPowers6(lTemp) = lTemp * cl2Exp6
        clPowers12(lTemp) = lTemp * cl2Exp12
        clPowers18(lTemp) = lTemp * cl2Exp18
    Next lTemp

    For lTemp = 0 To 255                            'Fill the translation table.
        Select Case lTemp
            Case 65 To 90
                cbTransFrom(lTemp) = lTemp - 65     'A - Z
            Case 97 To 122
                cbTransFrom(lTemp) = lTemp - 71     'a - z
            Case 48 To 57
                cbTransFrom(lTemp) = lTemp + 4      '1 - 0
            Case 43
                cbTransFrom(lTemp) = 62             'Chr(43) = "+"
            Case 47
                cbTransFrom(lTemp) = 63             'Chr(47) = "/"
        End Select
    Next lTemp

End Sub

Public Function Encode(sString As String) As String

    Dim bTrans(63) As Byte, bOut() As Byte, bIn() As Byte, lOutSize As Long
    Dim lChar As Long, lTrip As Long, iPad As Integer, lLen As Long, lTemp As Long, lPos As Long


    iPad = Len(sString) Mod 3                           'See if the length is divisible by 3
    If iPad Then                                        'If not, figure out the end pad and resize the input.
        iPad = 3 - iPad
        sString = sString & String(iPad, Chr(0))
    End If

    bIn = StrConv(sString, vbFromUnicode)               'Load the input string.
    lLen = ((UBound(bIn) + 1) \ 3) * 4                  'Length of resulting string.
    lTemp = lLen \ 72                                   'Added space for vbCrLfs.
    lOutSize = ((lTemp * 2) + lLen) - 1                 'Calculate the size of the output buffer.
    ReDim bOut(lOutSize)                                'Make the output buffer.

    lLen = 0                                            'Reusing this one, so reset it.

    For lChar = LBound(bIn) To UBound(bIn) Step 3
        lTrip = clPowers16(bIn(lChar)) + clPowers8(bIn(lChar + 1)) + bIn(lChar + 2)    'Combine the 3 bytes
        lTemp = lTrip And clOneMask                     'Mask for the first 6 bits
        bOut(lPos) = cbTransTo(lTemp \ cl2Exp18)        'Shift it down to the low 6 bits and get the value
        lTemp = lTrip And clTwoMask                     'Mask for the second set.
        bOut(lPos + 1) = cbTransTo(lTemp \ cl2Exp12)    'Shift it down and translate.
        lTemp = lTrip And clThreeMask                   'Mask for the third set.
        bOut(lPos + 2) = cbTransTo(lTemp \ cl2Exp6)     'Shift it down and translate.
        bOut(lPos + 3) = cbTransTo(lTrip And clFourMask) 'Mask for the low set.
        If lLen = 68 Then                               'Ready for a newline
            bOut(lPos + 4) = 13                         'Chr(13) = vbCr
            bOut(lPos + 5) = 10                         'Chr(10) = vbLf
            lLen = 0                                    'Reset the counter
            lPos = lPos + 6
        Else
            lLen = lLen + 4
            lPos = lPos + 4
        End If
    Next lChar

    If bOut(lOutSize) = 10 Then lOutSize = lOutSize - 2 'Shift the padding chars down if it ends with CrLf.

    If iPad = 1 Then                                    'Add the padding chars if any.
        bOut(lOutSize) = 61                             'Chr(61) = "="
    ElseIf iPad = 2 Then
        bOut(lOutSize) = 61
        bOut(lOutSize - 1) = 61
    End If

    Encode = StrConv(bOut, vbUnicode)                   'Convert back to a string and return it.

End Function

生成的输出完全如下: Required Output

我试图在VB.Net中实现相同的输出,但我无法这样做。我尝试使用以下内容:

Dim testStr As String = "test.xlsm"
Dim byt As Byte() = Encoding.Default.GetBytes(testStr)
testStr = Convert.ToBase64String(byt)

输入字符串:http://txt.do/obff

但我没有得到完全相同的字符串。第一行在两种情况下都不同(VBA和VB.Net),我不确定原因。

必需输出(VBA和网络链接):

UEsDBBQABgAIAAAAIQCsmTVRbwEAAD8EAAATAAgCW0NvbnRlbnRfVHlwZXNdLnhtbCCiBAIooAACAAAAAAAAAAAAAAAAAAAAAAAA

生成输出(VB.Net)

UEsDBBQABgAIAAAAIQA/PzVRbwEAAD8EAAATAAgCW0NvbnRlbnRfVHlwZXNdLnhtbCA/BAIoPwACAAAAAAAAAAAAAAAAAAAAAAAAA

您能否告诉我出错的地方?如何在VB.Net中实现相同目标?

1 个答案:

答案 0 :(得分:1)

我设法直接获取文件,读取所有字节并将其转换为base64字符串来解决问题。

Dim dat As Byte() = IO.File.ReadAllBytes(FileName)
testStr = Convert.ToBase64String(dat, Base64FormattingOptions.InsertLineBreaks)