我在VB6工程中引用了 vbRichClient5.dll,代码如下Private Sub Command1_Click() Dim CR As New cCrypt debug.print CR.Base64Enc("中华人民共和国") End Sub 运行结果是 1tC7qsjLw/G5srrNufo=与第一楼的结果不一致,《中华人民共和国》 编码成 《5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9》 据说,此编码结果是利用 C# 自带的base64编码接口,好像是GBK字符集。 或者请bcrun版主提供调用.net组件中的base64接口办法?多谢了。
Option Explicit Private Const cstBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" Private arrBase64() As StringPublic Function Base64Encode(strSource As String) As String On Error Resume Next If UBound(arrBase64) = -1 Then arrBase64 = Split(StrConv(cstBase64, vbUnicode), vbNullChar) End If Dim arrB() As Byte, bTmp(2) As Byte, bT As Byte Dim I As Long, J As Long arrB = StrConv(strSource, vbFromUnicode)
J = UBound(arrB) For I = 0 To J Step 3 Erase bTmp bTmp(0) = arrB(I + 0) bTmp(1) = arrB(I + 1) bTmp(2) = arrB(I + 2)
bT = (bTmp(1) And 15) * 4 bT = bT + bTmp(2) / 64 If I + 1 <= J Then Base64Encode = Base64Encode & arrBase64(bT) Else Base64Encode = Base64Encode & "=" End If
bT = bTmp(2) And 63 If I + 2 <= J Then Base64Encode = Base64Encode & arrBase64(bT) Else Base64Encode = Base64Encode & "=" End If Next End Function 'Unicode转换为UTF-8. Public Function UTF8_Encode(ByVal strUnicode As String) As Byte() ' As String 'ByVal strUnicode As Byte Dim TLen As Long TLen = Len(strUnicode) If TLen = 0 Then Exit Function Dim lBufferSize As Long Dim lResult As Long Dim b() As Byte
If lResult Then lResult = lResult - 1 ReDim Preserve b(lResult) UTF8_Encode = b 'StrConv(b, vbUnicode) '此处为 Tiger_Zhao 修正 End If End FunctionPrivate Sub Command2_Click() Debug.Print Base64Encode(UTF8_Encode("中华人民共和国")) '返回结果:P6On3FN/plUhdtuOo3vYh/ZJ 并不是 5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9 End Sub
但具体怎么实现,我没有试过,请大侠帮忙。
按他Base64的长度:28字符
就知道,先把7个汉字转换出UTF-8编码(21字节),
再把这个UTF-8编码转Base64(28字符)。
如果这7个汉字按ANSI码或Unicode码(都是14字节)来转Base64,结果都是20个字符。
回复 bcrun 版主:我并不是刻意要求引用js文件,实在是因为找不到实现一楼编码效果的函数,而百度可以搜索到的编码,都似乎是GB2312的字符集或规则,不能解决一楼编码效果(或规则)。引用js文件,可能需要使用WebBrowser1控件,反而降低了程序的运行效率(海量数据),既然提到有免费的库(dll或类模块,以及其它),可否直接将此文件发给我么? 我的信箱是 [email protected] 多谢bcrun版主相助。
我正在看 ,正是 bcrun 版主 大作,辛苦了。
Dim CR As New cCrypt
debug.print CR.Base64Enc("中华人民共和国")
End Sub
运行结果是 1tC7qsjLw/G5srrNufo=与第一楼的结果不一致,《中华人民共和国》 编码成 《5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9》
据说,此编码结果是利用 C# 自带的base64编码接口,好像是GBK字符集。
或者请bcrun版主提供调用.net组件中的base64接口办法?多谢了。
思路不对,你在F2中查找base64,就会看到有个cCrypt类有Base64Enc和Base64Dec方法了
我在第10楼,引用并使用该函数,编码后的结果不对。能否提供调用.net组件中的base64接口办法?多谢了。
而对字符串(VB 中的 String)编码需要先用某种编码进行 String -> Byte数组 的转换。这里选用编码(ANSI、Unicode、UTF-8等)不同就有不同的结果。CryptoJS.enc.Utf8.parse 明显是 UTF-8 的,
先用这个帖子中的 UTF8_Encode(我7楼修正的方式,并且返回类型改为 Byte())转换,
再用普通的 Base-64 函数,
得到正确结果 5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9 。
Option Explicit
Private Const cstBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Private arrBase64() As StringPublic Function Base64Encode(strSource As String) As String
On Error Resume Next
If UBound(arrBase64) = -1 Then
arrBase64 = Split(StrConv(cstBase64, vbUnicode), vbNullChar)
End If
Dim arrB() As Byte, bTmp(2) As Byte, bT As Byte
Dim I As Long, J As Long
arrB = StrConv(strSource, vbFromUnicode)
J = UBound(arrB)
For I = 0 To J Step 3
Erase bTmp
bTmp(0) = arrB(I + 0)
bTmp(1) = arrB(I + 1)
bTmp(2) = arrB(I + 2)
bT = (bTmp(0) And 252) / 4
Base64Encode = Base64Encode & arrBase64(bT)
bT = (bTmp(0) And 3) * 16
bT = bT + bTmp(1) / 16
Base64Encode = Base64Encode & arrBase64(bT)
bT = (bTmp(1) And 15) * 4
bT = bT + bTmp(2) / 64
If I + 1 <= J Then
Base64Encode = Base64Encode & arrBase64(bT)
Else
Base64Encode = Base64Encode & "="
End If
bT = bTmp(2) And 63
If I + 2 <= J Then
Base64Encode = Base64Encode & arrBase64(bT)
Else
Base64Encode = Base64Encode & "="
End If
Next
End Function
'Unicode转换为UTF-8.
Public Function UTF8_Encode(ByVal strUnicode As String) As Byte() ' As String 'ByVal strUnicode As Byte
Dim TLen As Long
TLen = Len(strUnicode)
If TLen = 0 Then Exit Function
Dim lBufferSize As Long
Dim lResult As Long
Dim b() As Byte
lBufferSize = TLen * 3 + 1
ReDim b(lBufferSize - 1)
lResult = WideCharToMultiByte(CP_UTF8, 0, StrPtr(strUnicode), TLen, b(0), lBufferSize, vbNullString, 0)
If lResult Then
lResult = lResult - 1
ReDim Preserve b(lResult)
UTF8_Encode = b 'StrConv(b, vbUnicode) '此处为 Tiger_Zhao 修正
End If
End FunctionPrivate Sub Command2_Click()
Debug.Print Base64Encode(UTF8_Encode("中华人民共和国"))
'返回结果:P6On3FN/plUhdtuOo3vYh/ZJ 并不是 5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9
End Sub
这是 ANSI 编码,改用 UTF8_Encode。
你连自己的代码都不明白!
但在“版主大人”的光环面前,
楼主似乎已经看不到俺这种小人物的存在了。UTF-8编码转BASE64那个,不知道怎么最后的两个字符不一样。
BASE64算法的代码是我1个多月前写的。
当时进行过好多次测试,经验证是正确的呢。
本来今天想手工处理一下,看结果究竟应该是啥,
只是上班太忙了,没来得及。
这个只有明天处理了。
我自己编写的方法首先要有一个 Base64Encode(Byte()) 的函数,然后再封装出各种的 Base64EncodeA(String)、Base64EncodeU(String)……
只是想着,把A格式编码的文本,转为B格式;B格式的能转回来。
主要目的是完成自己的代码算法。
因为当时在“百度百科”看到的VB6代码,
我的评价是:又长又臭!
因为并没有牵涉到具体的应用环境,
在“参数”上没去管那么多(并且也没打算“发表出来”)。今天也发现出出错的原因,并不是BASE54算法错误。
是因为7个汉字的UTF8编码是21字节,
那儿调用Strconv()时,第21字节“单了1个”,它变成空字符了,
传入编码函数,第21字节由非0变成0。
因此最后2个码不一样了。
我试了一下再加个汉字在后面,
转出来的BASE64码就正确了(前28个跟楼主的一致)。
#pragma comment(lib,"crypt32")
#include <windows.h>
#include <stdio.h>
#include <tchar.h>//+-------------------------------------------------------------------------
// convert formatted string to binary
// If cchString is 0, then pszString is NULL terminated and
// cchString is obtained via strlen() + 1.
// dwFlags defines string format
// if pbBinary is NULL, *pcbBinary returns the size of required memory
// *pdwSkip returns the character count of skipped strings, optional
// *pdwFlags returns the actual format used in the conversion, optional
//--------------------------------------------------------------------------
BOOL
WINAPI
CryptStringToBinaryA(
IN LPCSTR pszString,
IN DWORD cchString,
IN DWORD dwFlags,
IN BYTE *pbBinary,
IN OUT DWORD *pcbBinary,
OUT DWORD *pdwSkip, //OPTIONAL
OUT DWORD *pdwFlags //OPTIONAL
);
//+-------------------------------------------------------------------------
// convert formatted string to binary
// If cchString is 0, then pszString is NULL terminated and
// cchString is obtained via strlen() + 1.
// dwFlags defines string format
// if pbBinary is NULL, *pcbBinary returns the size of required memory
// *pdwSkip returns the character count of skipped strings, optional
// *pdwFlags returns the actual format used in the conversion, optional
//--------------------------------------------------------------------------
BOOL
WINAPI
CryptStringToBinaryW(
IN LPCWSTR pszString,
IN DWORD cchString,
IN DWORD dwFlags,
IN BYTE *pbBinary,
IN OUT DWORD *pcbBinary,
OUT DWORD *pdwSkip, //OPTIONAL
OUT DWORD *pdwFlags //OPTIONAL
);
#ifdef UNICODE
#define CryptStringToBinary CryptStringToBinaryW
#else
#define CryptStringToBinary CryptStringToBinaryA
#endif // !UNICODE//+-------------------------------------------------------------------------
// convert binary to formatted string
// dwFlags defines string format
// if pszString is NULL, *pcchString returns the size of required memory in byte
//--------------------------------------------------------------------------
BOOL
WINAPI
CryptBinaryToStringA(
IN CONST BYTE *pbBinary,
IN DWORD cbBinary,
IN DWORD dwFlags,
IN LPSTR pszString,
IN OUT DWORD *pcchString
);
//+-------------------------------------------------------------------------
// convert binary to formatted string
// dwFlags defines string format
// if pszString is NULL, *pcchString returns the size of required memory in byte
//--------------------------------------------------------------------------
BOOL
WINAPI
CryptBinaryToStringW(
IN CONST BYTE *pbBinary,
IN DWORD cbBinary,
IN DWORD dwFlags,
IN LPWSTR pszString,
IN OUT DWORD *pcchString
);
#ifdef UNICODE
#define CryptBinaryToString CryptBinaryToStringW
#else
#define CryptBinaryToString CryptBinaryToStringA
#endif // !UNICODE// dwFlags has the following defines
#define CRYPT_STRING_BASE64HEADER 0x00000000
#define CRYPT_STRING_BASE64 0x00000001
#define CRYPT_STRING_BINARY 0x00000002
#define CRYPT_STRING_BASE64REQUESTHEADER 0x00000003
#define CRYPT_STRING_HEX 0x00000004
#define CRYPT_STRING_HEXASCII 0x00000005
#define CRYPT_STRING_BASE64_ANY 0x00000006
#define CRYPT_STRING_ANY 0x00000007
#define CRYPT_STRING_HEX_ANY 0x00000008
#define CRYPT_STRING_BASE64X509CRLHEADER 0x00000009
#define CRYPT_STRING_HEXADDR 0x0000000a
#define CRYPT_STRING_HEXASCIIADDR 0x0000000b#define CRYPT_STRING_NOCR 0x80000000// CryptBinaryToString uses the following flags
// CRYPT_STRING_BASE64HEADER - base64 format with certificate begin
// and end headers
// CRYPT_STRING_BASE64 - only base64 without headers
// CRYPT_STRING_BINARY - pure binary copy
// CRYPT_STRING_BASE64REQUESTHEADER - base64 format with request begin
// and end headers
// CRYPT_STRING_BASE64X509CRLHEADER - base64 format with x509 crl begin
// and end headers
// CRYPT_STRING_HEX - only hex format
// CRYPT_STRING_HEXASCII - hex format with ascii char display
// CRYPT_STRING_HEXADDR - hex format with address display
// CRYPT_STRING_HEXASCIIADDR - hex format with ascii char and address display
//
// CryptBinaryToString accepts CRYPT_STRING_NOCR or'd into one of the above.
// When set, line breaks contain only LF, instead of CR-LF pairs.// CryptStringToBinary uses the following flags
// CRYPT_STRING_BASE64_ANY tries the following, in order:
// CRYPT_STRING_BASE64HEADER
// CRYPT_STRING_BASE64
// CRYPT_STRING_ANY tries the following, in order:
// CRYPT_STRING_BASE64_ANY
// CRYPT_STRING_BINARY -- should always succeed
// CRYPT_STRING_HEX_ANY tries the following, in order:
// CRYPT_STRING_HEXADDR
// CRYPT_STRING_HEXASCIIADDR
// CRYPT_STRING_HEXASCII
// CRYPT_STRING_HEX
char *flags[12]={
"CRYPT_STRING_BASE64HEADER",
"CRYPT_STRING_BASE64",
"CRYPT_STRING_BINARY",
"CRYPT_STRING_BASE64REQUESTHEADER",
"CRYPT_STRING_HEX",
"CRYPT_STRING_HEXASCII",
"CRYPT_STRING_BASE64_ANY",
"CRYPT_STRING_ANY",
"CRYPT_STRING_HEX_ANY",
"CRYPT_STRING_BASE64X509CRLHEADER",
"CRYPT_STRING_HEXADDR",
"CRYPT_STRING_HEXASCIIADDR",
};
#define MAXC 1024
BYTE b[22]={
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
0x41,0x42,0xB0,0xA1,0x4A,0x55,
};
BOOL r;
DWORD len,dwFlags;
TCHAR s[MAXC];
int _tmain() {
_tprintf(_T("API CryptBinaryToString in crypt32.dll Demonstration:\n"));
for (dwFlags=0;dwFlags<12;dwFlags++) {
if (dwFlags==2
|| dwFlags==6
|| dwFlags==7
|| dwFlags==8) continue;
r=CryptBinaryToString(b,22,dwFlags,NULL,&len);
if (!r) {
_tprintf(_T("CryptBinaryToString error!\n"));
return 1;
}
if (len>MAXC) {
_tprintf(_T("%d==len>MAXC==%d!\n"),len,MAXC);
return 2;
}
r=CryptBinaryToString(b,22,dwFlags,s,&len);
if (!r) {
_tprintf(_T("CryptBinaryToString error!\n"));
return 3;
}
_tprintf(_T("\n%s:[\n%s]\n"),flags[dwFlags],s);
}
return 0;
}
//API CryptBinaryToString in crypt32.dll Demonstration:
//
//CRYPT_STRING_BASE64HEADER:[
//-----BEGIN CERTIFICATE-----
//AAECAwQFBgcICQoLDA0OD0FCsKFKVQ==
//-----END CERTIFICATE-----
//]
//
//CRYPT_STRING_BASE64:[
//AAECAwQFBgcICQoLDA0OD0FCsKFKVQ==
//]
//
//CRYPT_STRING_BASE64REQUESTHEADER:[
//-----BEGIN NEW CERTIFICATE REQUEST-----
//AAECAwQFBgcICQoLDA0OD0FCsKFKVQ==
//-----END NEW CERTIFICATE REQUEST-----
//]
//
//CRYPT_STRING_HEX:[
// 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
// 41 42 b0 a1 4a 55
//]
//
//CRYPT_STRING_HEXASCII:[
// 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................
// 41 42 b0 a1 4a 55 AB..JU
//]
//
//CRYPT_STRING_BASE64X509CRLHEADER:[
//-----BEGIN X509 CRL-----
//AAECAwQFBgcICQoLDA0OD0FCsKFKVQ==
//-----END X509 CRL-----
//]
//
//CRYPT_STRING_HEXADDR:[
//0000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
//0010 41 42 b0 a1 4a 55
//]
//
//CRYPT_STRING_HEXASCIIADDR:[
//0000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................
//0010 41 42 b0 a1 4a 55 AB..JU
//]
//