1# 消息摘要计算(C/C++)
2
3对应的算法规格请查看[消息摘要计算算法规格](crypto-generate-message-digest-overview.md#支持的算法与规格)。
4
5## 在CMake脚本中链接相关动态库
6```txt
7   target_link_libraries(entry PUBLIC libohcrypto.so)
8```
9
10
11## 开发步骤
12
13在调用update接口传入数据时,可以[一次性传入所有数据](#摘要算法一次性传入),也可以把数据人工分段,然后[分段update](#分段摘要算法)。对于同一段数据而言,计算结果没有差异。对于数据量较大的数据,开发者可以根据实际需求选择是否分段传入。
14
15下面分别提供两种方式的示例代码。
16
17
18### 摘要算法(一次性传入)
19
201. 调用[OH_CryptoDigest_Create](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_create),指定摘要算法SHA256,生成摘要实例(OH_CryptoDigest)。
21
222. 调用[OH_CryptoDigest_Update](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_update),传入自定义消息,进行摘要更新计算。单次update长度没有限制。
23
243. 调用[OH_CryptoDigest_Final](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_final),获取摘要计算结果。
25
264. 调用[OH_CryptoDigest_GetLength](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_getlength),获取摘要计算长度,单位为字节。
27
285. 调用[OH_DigestCrypto_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_digestcrypto_destroy),销毁摘要实例(OH_CryptoDigest)。
29
30- 以下使用单次传入数据,获取摘要计算结果为例:
31
32```c++
33#include "CryptoArchitectureKit/crypto_common.h"
34#include "CryptoArchitectureKit/crypto_digest.h"
35#include <string.h>
36
37static OH_Crypto_ErrCode doTestMd()
38{
39    OH_Crypto_ErrCode ret;
40    OH_CryptoDigest *ctx = nullptr;
41    char *testData = const_cast<char *>("0123456789");
42    Crypto_DataBlob in = {.data = (uint8_t *)(testData), .len = strlen(testData)};
43    Crypto_DataBlob out = {.data = nullptr, .len = 0};
44    int mdLen = 0;
45    ret = OH_CryptoDigest_Create("SHA256", &ctx);
46    if (ret != CRYPTO_SUCCESS) {
47        return ret;
48    }
49    do {
50        ret = OH_CryptoDigest_Update(ctx, &in);
51        if (ret != CRYPTO_SUCCESS) {
52            break;
53        }
54        ret = OH_CryptoDigest_Final(ctx, &out);
55        if (ret != CRYPTO_SUCCESS) {
56            break;
57        }
58        mdLen = OH_CryptoDigest_GetLength(ctx);
59    } while (0);
60    OH_Crypto_FreeDataBlob(&out);
61    OH_DigestCrypto_Destroy(ctx);
62    return ret;
63}
64```
65
66### 分段摘要算法
67
681. 调用[OH_CryptoDigest_Create](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_create),指定摘要算法SHA256,生成摘要实例(OH_CryptoDigest)。
69
702. 传入自定义消息,将一次传入数据量设置为20字节,多次调用[OH_CryptoDigest_Update](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_update),进行摘要更新计算。
71
723. 调用[OH_CryptoDigest_Final](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_final),获取摘要计算结果。
73
744. 调用[OH_CryptoDigest_GetLength](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_getlength),获取摘要计算长度,单位为字节。
75
765. 调用[OH_DigestCrypto_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_digestcrypto_destroy),销毁摘要实例(OH_CryptoDigest)。
77
78- 以下使用分段传入数据,获取摘要计算结果为例:
79
80```c++
81#include <stdlib.h>
82#include "CryptoArchitectureKit/crypto_common.h"
83#include "CryptoArchitectureKit/crypto_digest.h"
84#define OH_CRYPTO_DIGEST_DATA_MAX (1024 * 1024 * 100)
85
86static OH_Crypto_ErrCode doLoopMd()
87{
88    OH_Crypto_ErrCode ret;
89    OH_CryptoDigest *ctx = nullptr;
90    uint8_t *testData = (uint8_t *)malloc(OH_CRYPTO_DIGEST_DATA_MAX);
91    Crypto_DataBlob out = {.data = nullptr, .len = 0};
92    int mdLen = 0;
93    int isBlockSize = 20;
94    int offset = 0;
95
96    ret = OH_CryptoDigest_Create("SHA256", &ctx);
97    if (ret != CRYPTO_SUCCESS) {
98        return ret;
99    }
100    do {
101        for (int i = 0; i < 640 / isBlockSize; i++) {
102            Crypto_DataBlob in = {.data = reinterpret_cast<uint8_t *>(testData + offset),
103                                .len = static_cast<size_t>(isBlockSize)};
104            ret = OH_CryptoDigest_Update(ctx, &in);
105            if (ret != CRYPTO_SUCCESS) {
106                break;
107            }
108            offset += isBlockSize;
109        }
110        ret = OH_CryptoDigest_Final(ctx, &out);
111        if (ret != CRYPTO_SUCCESS) {
112            break;
113        }
114        mdLen = OH_CryptoDigest_GetLength(ctx);
115    } while (0);
116    OH_Crypto_FreeDataBlob(&out);
117    OH_DigestCrypto_Destroy(ctx);
118    return ret;
119}
120```
121