主頁 > 軟體工程 > VBA(VB)如何實作PHP中函式hash_hmac(‘sha512’, $data, $key)的功能?

VBA(VB)如何實作PHP中函式hash_hmac(‘sha512’, $data, $key)的功能?

2020-09-18 22:02:07 軟體工程

PHP中有個函式:hash_hmac(‘sha512’, $data, $key)
請大神移植到VBA中。(如果有VB現成的也可以)

我想自己移值,但有以下不理解:
其實,我對這個函式理解有些疑問:按我的理解,哈希(Sha512)是對$data求散列值,怎么這里多出一個$key呢?$key按解釋來說,就是作為密碼,進行驗證,難不成Sha512計算可逆?

(我的理解:Sha512本質是一元計算,就是只需要一個引數,且計算不可逆)

uj5u.com熱心網友回復:

求“散列值”的演算法,應該都是不可逆的吧。
你既然接觸到PHP,那你首先應該搞清楚hash_hmac()的作用、各個引數的含義吧!

按一般的API規律,實作sha512演算法的函式,一個是輸入資料的指標(資料首址),另一個會是資料長度(資料有多少位元組)。
你這兒的 $Key 會不會并不是密碼,而是表示資料長度的變數呢?

uj5u.com熱心網友回復:

使用 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.  截取你所需要的長度。

uj5u.com熱心網友回復:

不要做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

共享臨時文本檔案這種行程之間的通訊方法相比其它方法的優點有很多,下面僅列出我現在能想到的:
·行程之間松耦合
·行程可在同一臺機器上,也可跨機,跨作業系統,跨硬體平臺,甚至跨國。
·方便除錯和監視,只需讓第三方或人工查看該臨時文本檔案即可。
·方便在線開關服務,只需洗掉或創建該臨時文本檔案即可。
·方便實作分布式和負載均衡。
·方便佇列化提供服務,而且幾乎不可能發生佇列滿的情況(除非硬碟空間滿)
·……

“跨語言、跨機,跨作業系統,跨硬體平臺,跨國,跨*.*的”苦海無邊,
回頭是“使用共享純文本檔案進行資訊交流”的岸!

uj5u.com熱心網友回復:

參考 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中怎么解決?

uj5u.com熱心網友回復:

參考 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中怎么解決?

uj5u.com熱心網友回復:

對了,類似
Sha512($data)
的函式已經有了。就問下,怎么弄出:帶有密鑰的哈希值?

uj5u.com熱心網友回復:

僅供參考:
#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

uj5u.com熱心網友回復:

再供參考:
#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繼續
//
//程式成功執行完畢
//

uj5u.com熱心網友回復:

8樓,最后那兒……HMAC 的位數怎么是0呢?

uj5u.com熱心網友回復:

參考 9 樓 Chen8013 的回復:
8樓,最后那兒……HMAC 的位數怎么是0呢?

可能因為偶用的電腦是十年前公司給配的Windows Server 2003吧。

uj5u.com熱心網友回復:

##############################################################
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

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/76790.html

標籤:VBA

上一篇:VB中關于prodave6.0讀取資料塊函式的引數解釋

下一篇:WIN 7 利用SHDocVw.ShellWindows 獲取不到 非輸入網址開啟的IE瀏覽器(鏈接)?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more