VBA(VB)如何实现PHP中函数hash_hmac(‘sha512’, $data, $key)的功能?

qq_34666434 2016-04-15 08:15:49
PHP中有个函数:hash_hmac(‘sha512’, $data, $key)
请大神移植到VBA中。(如果有VB现成的也可以)

我想自己移值,但有以下不理解:
其实,我对这个函数理解有些疑问:按我的理解,哈希(Sha512)是对$data求散列值,怎么这里多出一个$key呢?$key按解释来说,就是作为密码,进行验证,难不成Sha512计算可逆?

(我的理解:Sha512本质是一元计算,就是只需要一个参数,且计算不可逆)
...全文
1201 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
用户 昵称 2016-04-26
  • 打赏
  • 举报
回复
############################################################## Keyed-Hash Message Authentication Code (HMAC) Hashlen = 512 ############################################################## Key length = 128 Tag length = 64 Input Date: "Sample message for keylen=blocklen" Text is 5361 6D706C65 206D6573 73616765 20666F72 206B6579 6C656E3D 626C6F63 6B6C656E Key is 00010203 04050607 08090A0B 0C0D0E0F 10111213 14151617 18191A1B 1C1D1E1F 20212223 24252627 28292A2B 2C2D2E2F 30313233 34353637 38393A3B 3C3D3E3F 40414243 44454647 48494A4B 4C4D4E4F 50515253 54555657 58595A5B 5C5D5E5F 60616263 64656667 68696A6B 6C6D6E6F 70717273 74757677 78797A7B 7C7D7E7F -------------------------------------------------------------- K0 is 00010203 04050607 08090A0B 0C0D0E0F 10111213 14151617 18191A1B 1C1D1E1F 20212223 24252627 28292A2B 2C2D2E2F 30313233 34353637 38393A3B 3C3D3E3F 40414243 44454647 48494A4B 4C4D4E4F 50515253 54555657 58595A5B 5C5D5E5F 60616263 64656667 68696A6B 6C6D6E6F 70717273 74757677 78797A7B 7C7D7E7F K0^ipad is 36373435 32333031 3E3F3C3D 3A3B3839 26272425 22232021 2E2F2C2D 2A2B2829 16171415 12131011 1E1F1C1D 1A1B1819 06070405 02030001 0E0F0C0D 0A0B0809 76777475 72737071 7E7F7C7D 7A7B7879 66676465 62636061 6E6F6C6D 6A6B6869 56575455 52535051 5E5F5C5D 5A5B5859 46474445 42434041 4E4F4C4D 4A4B4849 Hash((Key^ipad)||text) is 515C86E0 DD382747 A20BDD27 05AF56C1 AB87AA1D A14F3EFD D99A5935 08EC520D 60C10643 A3841B1E CA7EEFF9 559F5D00 78F93479 58FCA632 1E58769D 15CF3A15 K0 xor opad is 5C5D5E5F 58595A5B 54555657 50515253 4C4D4E4F 48494A4B 44454647 40414243 7C7D7E7F 78797A7B 74757677 70717273 6C6D6E6F 68696A6B 64656667 60616263 1C1D1E1F 18191A1B 14151617 10111213 0C0D0E0F 08090A0B 04050607 00010203 3C3D3E3F 38393A3B 34353637 30313233 2C2D2E2F 28292A2B 24252627 20212223 Hash((K0^opad)||Hash((K0^ipad)||text)) is FC25E240 658CA785 B7A811A8 D3F7B4CA 48CFA26A 8A366BF2 CD1F836B 05FCB024 BD368530 81811D6C EA4216EB AD79DA1C FCB95EA4 586B8A0C E356596A 55FB1347 -------------------------------------------------------------- mac is FC25E240 658CA785 B7A811A8 D3F7B4CA 48CFA26A 8A366BF2 CD1F836B 05FCB024 BD368530 81811D6C EA4216EB AD79DA1C FCB95EA4 586B8A0C E356596A 55FB1347
赵4老师 2016-04-18
  • 打赏
  • 举报
回复
引用 9 楼 Chen8013 的回复:
8楼,最后那儿……HMAC 的位数怎么是0呢?
可能因为偶用的电脑是十年前公司给配的Windows Server 2003吧。
赵4老师 2016-04-15
  • 打赏
  • 举报
回复
不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如: A将请求数据写到文件a.txt,写完后改名为aa.txt B发现aa.txt存在时,读取其内容,调用相应功能,将结果写到文件b.txt,写完后删除aa.txt,改名为bb.txt A发现bb.txt存在时,读取其内容,读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境,B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢? 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话,文本文件的格式问题可参考json或xml 共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出我现在能想到的: ·进程之间松耦合 ·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。 ·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务,只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满) ·…… “跨语言、跨机,跨操作系统,跨硬件平台,跨国,跨*.*的”苦海无边, 回头是“使用共享纯文本文件进行信息交流”的岸!
of123 2016-04-15
  • 打赏
  • 举报
回复
使用 key 的目的,是使用验证者能够确认 MAC 来自 key 的持有者。 首先,你找到一段求 SHA-512 的代码,作为处理的核心。 其次,按以下流程处理: 1. 将 key 用后续 0 填充成一个消息分组(128 字节)。我们暂且称其为密钥块。 2. 将密钥块所有字节与 &H36(ipad)异或得到输入首分组。 3. 将消息(data)填充后链接在输入首分组之后,用 SHA-512 求 Hash。 4. 将密钥块所有字节与 &H5C(opad)异或得到输出首分组。 5. 将 Hash 作为消息填充后链接在输出首分组之后,用 SHA-512 求 MAC。 6. 截取你所需要的长度。
舉杯邀明月 2016-04-15
  • 打赏
  • 举报
回复
求“散列值”的算法,应该都是不可逆的吧。 你既然接触到PHP,那你首先应该搞清楚hash_hmac()的作用、各个参数的含义吧! 按一般的API规律,实现sha512算法的函数,一个是输入数据的指针(数据首址),另一个会是数据长度(数据有多少字节)。 你这儿的 $Key 会不会并不是密码,而是表示数据长度的变量呢?
舉杯邀明月 2016-04-15
  • 打赏
  • 举报
回复
8楼,最后那儿……HMAC 的位数怎么是0呢?
赵4老师 2016-04-15
  • 打赏
  • 举报
回复
仅供参考:
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "advapi32.lib")
#define _WIN32_WINNT 0x0400
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define KEYLENGTH  0x00800000
void HandleError(char *s);
//--------------------------------------------------------------------
//  These additional #define statements are required.
#define ENCRYPT_ALGORITHM CALG_RC4
#define ENCRYPT_BLOCK_SIZE 8
//   Declare the function EncryptFile. The function definition
//   follows main.
BOOL EncryptFile(
    PCHAR szSource,
    PCHAR szDestination,
    PCHAR szPassword);
//--------------------------------------------------------------------
//   Begin main.
void main(void) {
    CHAR szSource[100];
    CHAR szDestination[100];
    CHAR szPassword[100];
    printf("Encrypt a file. \n\n");
    printf("Enter the name of the file to be encrypted: ");
    scanf("%s",szSource);
    printf("Enter the name of the output file: ");
    scanf("%s",szDestination);
    printf("Enter the password:");
    scanf("%s",szPassword);
    //--------------------------------------------------------------------
    // Call EncryptFile to do the actual encryption.
    if(EncryptFile(szSource, szDestination, szPassword)) {
        printf("Encryption of the file %s was a success. \n", szSource);
        printf("The encrypted data is in file %s.\n",szDestination);
    } else {
        HandleError("Error encrypting file!");
    }
} // End of main
//--------------------------------------------------------------------
//   Code for the function EncryptFile called by main.
static BOOL EncryptFile(
    PCHAR szSource,
    PCHAR szDestination,
    PCHAR szPassword)
//--------------------------------------------------------------------
//   Parameters passed are:
//     szSource, the name of the input, a plaintext file.
//     szDestination, the name of the output, an encrypted file to be
//         created.
//     szPassword, the password.
{
    //--------------------------------------------------------------------
    //   Declare and initialize local variables.
    FILE *hSource;
    FILE *hDestination;
    HCRYPTPROV hCryptProv;
    HCRYPTKEY hKey;
    HCRYPTHASH hHash;
    PBYTE pbBuffer;
    DWORD dwBlockLen;
    DWORD dwBufferLen;
    DWORD dwCount;
    //--------------------------------------------------------------------
    // Open source file.
    if(hSource = fopen(szSource,"rb")) {
        printf("The source plaintext file, %s, is open. \n", szSource);
    } else {
        HandleError("Error opening source plaintext file!");
    }
    //--------------------------------------------------------------------
    // Open destination file.
    if(hDestination = fopen(szDestination,"wb")) {
        printf("Destination file %s is open. \n", szDestination);
    } else {
        HandleError("Error opening destination ciphertext file!");
    }
    //以下获得一个CSP句柄
    if(CryptAcquireContext(
                &hCryptProv,
                NULL,               //NULL表示使用默认密钥容器,默认密钥容器名
                //为用户登陆名
                NULL,
                PROV_RSA_FULL,
                0)) {
        printf("A cryptographic provider has been acquired. \n");
    } else {
        if(CryptAcquireContext(
                    &hCryptProv,
                    NULL,
                    NULL,
                    PROV_RSA_FULL,
                    CRYPT_NEWKEYSET))//创建密钥容器
        {
            //创建密钥容器成功,并得到CSP句柄
            printf("A new key container has been created.\n");
        } else {
            HandleError("Could not create a new key container.\n");
        }
    }
    //--------------------------------------------------------------------
    // 创建一个会话密钥(session key)
    // 会话密钥也叫对称密钥,用于对称加密算法。
    // (注: 一个Session是指从调用函数CryptAcquireContext到调用函数
    //   CryptReleaseContext 期间的阶段。会话密钥只能存在于一个会话过程)
    //--------------------------------------------------------------------
    // Create a hash object.
    if(CryptCreateHash(
                hCryptProv,
                CALG_MD5,
                0,
                0,
                &hHash)) {
        printf("A hash object has been created. \n");
    } else {
        HandleError("Error during CryptCreateHash!\n");
    }
    //--------------------------------------------------------------------
    // 用输入的密码产生一个散列
    if(CryptHashData(
                hHash,
                (BYTE *)szPassword,
                strlen(szPassword),
                0)) {
        printf("The password has been added to the hash. \n");
    } else {
        HandleError("Error during CryptHashData. \n");
    }
    //--------------------------------------------------------------------
    // 通过散列生成会话密钥
    if(CryptDeriveKey(
                hCryptProv,
                ENCRYPT_ALGORITHM,
                hHash,
                KEYLENGTH,
                &hKey)) {
        printf("An encryption key is derived from the password hash. \n");
    } else {
        HandleError("Error during CryptDeriveKey!\n");
    }
    //--------------------------------------------------------------------
    // Destroy the hash object.
    CryptDestroyHash(hHash);
    hHash = NULL;
    //--------------------------------------------------------------------
    //  The session key is now ready.
    //--------------------------------------------------------------------
    // 因为加密算法是按ENCRYPT_BLOCK_SIZE 大小的块加密的,所以被加密的
    // 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的
    // 数据长度。
    dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
    //--------------------------------------------------------------------
    // Determine the block size. If a block cipher is used,
    // it must have room for an extra block.
    if(ENCRYPT_BLOCK_SIZE > 1)
        dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
    else
        dwBufferLen = dwBlockLen;
    //--------------------------------------------------------------------
    // Allocate memory.
    if(pbBuffer = (BYTE *)malloc(dwBufferLen)) {
        printf("Memory has been allocated for the buffer. \n");
    } else {
        HandleError("Out of memory. \n");
    }
    //--------------------------------------------------------------------
    // In a do loop, encrypt the source file and write to the destination file.
    do {
        //--------------------------------------------------------------------
        // Read up to dwBlockLen bytes from the source file.
        dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);
        if(ferror(hSource)) {
            HandleError("Error reading plaintext!\n");
        }
        //--------------------------------------------------------------------
        // 加密数据
        if(!CryptEncrypt(
                    hKey,           //密钥
                    0,              //如果数据同时进行散列和加密,这里传入一个
                    //散列对象
                    feof(hSource),  //如果是最后一个被加密的块,输入TRUE.如果不是输.
                    //入FALSE这里通过判断是否到文件尾来决定是否为
                    //最后一块。
                    0,              //保留
                    pbBuffer,       //输入被加密数据,输出加密后的数据
                    &dwCount,       //输入被加密数据实际长度,输出加密后数据长度
                    dwBufferLen))   //pbBuffer的大小。
        {
            HandleError("Error during CryptEncrypt. \n");
        }
        //--------------------------------------------------------------------
        // Write data to the destination file.
        fwrite(pbBuffer, 1, dwCount, hDestination);
        if(ferror(hDestination)) {
            HandleError("Error writing ciphertext.");
        }
    } while(!feof(hSource));
    //--------------------------------------------------------------------
    //  End the do loop when the last block of the source file has been
    //  read, encrypted, and written to the destination file.
    //--------------------------------------------------------------------
    // Close files.
    if(hSource)
        fclose(hSource);
    if(hDestination)
        fclose(hDestination);
    //--------------------------------------------------------------------
    // Free memory.
    if(pbBuffer)
        free(pbBuffer);
    //--------------------------------------------------------------------
    // Destroy session key.
    if(hKey)
        CryptDestroyKey(hKey);
    //--------------------------------------------------------------------
    // Destroy hash object.
    if(hHash)
        CryptDestroyHash(hHash);
    //--------------------------------------------------------------------
    // Release provider handle.
    if(hCryptProv)
        CryptReleaseContext(hCryptProv, 0);
    return(TRUE);
} // End of Encryptfile
//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.
void HandleError(char *s) {
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError

赵4老师 2016-04-15
  • 打赏
  • 举报
回复
再供参考:
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "advapi32.lib")
#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <wincrypt.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
void HandleError(TCHAR* s);
void Wait(TCHAR* s);
int _tmain(int argc, _TCHAR* argv[]) {
    HCRYPTPROV hProv;
    LPTSTR pszName;
    DWORD dwType;
    DWORD cbName;
    DWORD dwIndex = 0;
    BYTE* ptr;
    ALG_ID aiAlgid;
    DWORD dwBits;
    DWORD dwNameLen;
    CHAR szName[100];
    BYTE pbData[1024];
    DWORD cbData = 1024;
    DWORD dwIncrement = sizeof(DWORD);
    DWORD dwFlags = CRYPT_FIRST;
    DWORD dwParam = PP_CLIENT_HWND;
    CHAR* pszAlgType = NULL;
    BOOL fMore = TRUE;
    printf("列举可用的CSP提供者类型\n");
    printf("CSP提供者类型  CSP提供者类型名称\n");
    _tprintf(TEXT("_____________  __________________________________________________\n"));
    //循环调用CryptEnumProviderType函数枚举当前计算机支持的CSP类型
    while(CryptEnumProviderTypes(dwIndex, NULL, 0,
                                 &dwType,
                                 NULL, //第一次调用设置为NULL
                                 &cbName)) //将要输出的pszName的长度
    {
        //为pszName分配内存
        if(!(pszName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbName))) {
            HandleError(TEXT("调用LocalAlloc分配内存出错\n"));
        }
        //获取CSP提供者类型名
        if(CryptEnumProviderTypes(dwIndex++, NULL, 0,
                                  &dwType, pszName, &cbName)) {
            _tprintf(TEXT("%13d  %s\n"), dwType, pszName);
        } else {
            HandleError(TEXT("调用CryptEnumProviderTypes出错\n"));
        }
        LocalFree(pszName);
    }
    //连接CSP,创建CSP句柄
    if(!CryptAcquireContext(&hProv, NULL, NULL,
                            PROV_RSA_FULL, NULL)) {
        HandleError(TEXT("调用CryptAcquireContext函数出错\n"));
    }
    //获得CSP参数,枚举支持的密码算法
    printf("\n枚举支持的密码算法\n");
    printf("算法ID     位数  类型  长度  算法名称\n");
    printf("_________  ____  ____  ____  ____________________\n");
    while(fMore) {
        if(CryptGetProvParam(hProv, PP_ENUMALGS, pbData,
                             &cbData, dwFlags)) {
            //从pbData缓冲区中解析出算法信息
            dwFlags = 0;
            ptr = pbData;
            aiAlgid = *(ALG_ID*)ptr;
            ptr += sizeof(ALG_ID);
            dwBits = *(DWORD*)ptr;
            ptr += dwIncrement;
            dwNameLen = *(DWORD*)ptr;
            ptr += dwIncrement;
            strncpy(szName, (char*)ptr, __min(dwNameLen,99));szName[__min(dwNameLen,99)]=0;
            //获取算法类型
            switch(GET_ALG_CLASS(aiAlgid)) {
            case ALG_CLASS_DATA_ENCRYPT:
                pszAlgType = "加密";
                break;
            case ALG_CLASS_HASH:
                pszAlgType = "哈希";
                break;
            case ALG_CLASS_KEY_EXCHANGE:
                pszAlgType = "交换";
                break;
            case ALG_CLASS_SIGNATURE:
                pszAlgType = "签名";
                break;
            default:
                pszAlgType = "未知";
                break;
            }
            //打印算法信息
            printf("%8.8xh  %4d  %4s  %4d  %s\n",
                   aiAlgid, dwBits, pszAlgType, dwNameLen, szName);
        } else {
            fMore = FALSE;
        }
    }
    Wait(TEXT("\n按Enter继续"));
    if(!(CryptReleaseContext(hProv, 0))) {
        HandleError(TEXT("调用CryptReleaseContext时出错\n"));
    }
    if(GetLastError() == ERROR_NO_MORE_ITEMS) {
        _tprintf(TEXT("\n程序成功执行完毕\n"));
    } else {
        HandleError(TEXT("读取算法信息时出错"));
    }
    return 0;
}
void HandleError(TCHAR* s) {
    _tprintf(TEXT("程序运行出现错误.\n"));
    _tprintf(TEXT("%s\n"),s);
    _tprintf(TEXT("错误代码%x\n."), GetLastError());
    _tprintf(TEXT("程序终止.\n"));
    exit(1);
}
void Wait(TCHAR* s) {
    char x;
    _tprintf(s);
    x = getchar();
}
//列举可用的CSP提供者类型
//CSP提供者类型  CSP提供者类型名称
//_____________  __________________________________________________
//            1  RSA Full (Signature and Key Exchange)
//            3  DSS Signature
//           12  RSA SChannel
//           13  DSS Signature with Diffie-Hellman Key Exchange
//           18  Diffie-Hellman SChannel
//           24  RSA Full and AES
//
//枚举支持的密码算法
//算法ID     位数  类型  长度  算法名称
//_________  ____  ____  ____  ____________________
//00006602h   128  加密     4  RC2
//00006801h   128  加密     4  RC4
//00006601h    56  加密     4  DES
//00006609h   112  加密    13  3DES TWO KEY
//00006603h   168  加密     5  3DES
//00008004h   160  哈希     6  SHA-1
//00008001h   128  哈希     4  MD2
//00008002h   128  哈希     4  MD4
//00008003h   128  哈希     4  MD5
//00008008h   288  哈希    12  SSL3 SHAMD5
//00008005h     0  哈希     4  MAC
//00002400h  1024  签名     9  RSA_SIGN
//0000a400h  1024  交换     9  RSA_KEYX
//00008009h     0  哈希     5  HMAC
//
//按Enter继续
//
//程序成功执行完毕
//
qq_34666434 2016-04-15
  • 打赏
  • 举报
回复
对了,类似 Sha512($data) 的函数已经有了。就问下,怎么弄出:带有密钥的哈希值?
qq_34666434 2016-04-15
  • 打赏
  • 举报
回复
引用 2 楼 of123 的回复:
使用 key 的目的,是使用验证者能够确认 MAC 来自 key 的持有者。 首先,你找到一段求 SHA-512 的代码,作为处理的核心。 其次,按以下流程处理: 1. 将 key 用后续 0 填充成一个消息分组(128 字节)。我们暂且称其为密钥块。 2. 将密钥块所有字节与 &H36(ipad)异或得到输入首分组。 3. 将消息(data)填充后链接在输入首分组之后,用 SHA-512 求 Hash。 4. 将密钥块所有字节与 &H5C(opad)异或得到输出首分组。 5. 将 Hash 作为消息填充后链接在输出首分组之后,用 SHA-512 求 MAC。 6. 截取你所需要的长度。
首先,感谢您的回答! 在此解释一下PHP这个函数的用法:四个参数,我的例子用了三个,前三个参数必选,第四个为可选参数(我在网上查的) hash_hmac — 使用 HMAC 方法生成带有密钥的哈希值 (带有密钥的哈希值,这怎么理解) string hash_hmac(string $algo, string $data, string $key[, bool $raw_output = false]) 参数: algo:要使用的哈希算法名称,例如:"md5","sha256","haval160,4", "sha512""等。 data:要进行哈希运算的消息。 key:使用 HMAC 生成信息摘要时所使用的密钥。 raw_output:(此参数为可选)设置为 TRUE 输出原始二进制数据, 设置为 FALSE 输出小写 16 进制字符串。 返回值: 如果 raw_output 设置为 TRUE, 则返回原始二进制数据表示的信息摘要,否则返回 16 进制小写字符串格式表示的信息摘要。 如果 algo 参数指定的不是受支持的算法,返回 FALSE。  此函数一般情形返回一个对应哈希位数的16进制信息摘要(sha512返回128位的16进制形式的字符串) 问:VBA中怎么解决?
qq_34666434 2016-04-15
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如: A将请求数据写到文件a.txt,写完后改名为aa.txt B发现aa.txt存在时,读取其内容,调用相应功能,将结果写到文件b.txt,写完后删除aa.txt,改名为bb.txt A发现bb.txt存在时,读取其内容,读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境,B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢? 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话,文本文件的格式问题可参考json或xml 共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出我现在能想到的: ·进程之间松耦合 ·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。 ·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务,只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满) ·…… “跨语言、跨机,跨操作系统,跨硬件平台,跨国,跨*.*的”苦海无边, 回头是“使用共享纯文本文件进行信息交流”的岸!
NONONO!怪我没说清楚,我说是要移值,其实不是真的移值,我本来就是用VBA来写程序的,只是。。。。我要编的东西,网站上只给出了一个PHP范例,我不能因为人家给的PHP范例,就搭个台子去学PHP,您说是吧? 话说PHP编就是方便,(但搭建编程分环境就不是那么友好了,各有优缺点吧),PHP中一个函数就能搞定的东西,VB要搞半天,还不明白。在此解释一下PHP这个函数的用法:(我在网上查的) hash_hmac — 使用 HMAC 方法生成带有密钥的哈希值 string hash_hmac(string $algo, string $data, string $key[, bool $raw_output = false]) 参数: algo:要使用的哈希算法名称,例如:"md5","sha256","haval160,4", "sha512""等。 data:要进行哈希运算的消息。 key:使用 HMAC 生成信息摘要时所使用的密钥。 raw_output:(此参数为可选)设置为 TRUE 输出原始二进制数据, 设置为 FALSE 输出小写 16 进制字符串。 返回值: 如果 raw_output 设置为 TRUE, 则返回原始二进制数据表示的信息摘要,否则返回 16 进制小写字符串格式表示的信息摘要。 如果 algo 参数指定的不是受支持的算法,返回 FALSE。  此函数一般情形返回一个对应哈希位数的16进制信息摘要(sha512返回128位的16进制形式的字符串) 问:VBA中怎么解决?

2,462

社区成员

发帖
与我相关
我的任务
社区描述
VBA(Visual Basic for Applications)是Visual Basic的一种宏语言,是在其桌面应用程序中执行通用的自动化(OLE)任务的编程语言。
社区管理员
  • VBA
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧