LCOV - code coverage report
Current view: top level - legacy/ascend910/framework/nslbdp - hccl_nslb_md5.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 199 0
Test Date: 2026-07-28 12:11:00 Functions: 0.0 % 24 0

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include <fcntl.h>
      12              : #include <unistd.h>
      13              : #include <hccl/hccl_types.h>
      14              : #include "hccl_nslb_md5.h"
      15              : 
      16              : namespace hccl {
      17              : 
      18              : // 初始化常量
      19              : const unsigned char NSLBMD5::PADDING[64] = {
      20              :     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      21              :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      22              :     0, 0, 0, 0, 0, 0, 0, 0, 0
      23              : };
      24              : 
      25              : const char NSLBMD5::HEX[16] = {
      26              :     '0', '1', '2', '3',
      27              :     '4', '5', '6', '7',
      28              :     '8', '9', 'a', 'b',
      29              :     'c', 'd', 'e', 'f'
      30              : };
      31              : 
      32              : // F, G, H, I 是4个基本MD5函数
      33            0 : inline uint32_t F(uint32_t x, uint32_t y, uint32_t z) {
      34            0 :     return (x & y) | (~x & z);
      35              : }
      36              : 
      37            0 : inline uint32_t G(uint32_t x, uint32_t y, uint32_t z) {
      38            0 :     return (x & z) | (y & ~z);
      39              : }
      40              : 
      41            0 : inline uint32_t H(uint32_t x, uint32_t y, uint32_t z) {
      42            0 :     return x ^ y ^ z;
      43              : }
      44              : 
      45            0 : inline uint32_t I(uint32_t x, uint32_t y, uint32_t z) {
      46            0 :     return y ^ (x | ~z);
      47              : }
      48              : 
      49              : // 左循环移位操作
      50            0 : inline uint32_t ROTATE_LEFT(uint32_t x, int n) {
      51            0 :     return (x << n) | (x >> (NSLB_MD5_RESERVE - n));
      52              : }
      53              : 
      54              : // FF, GG, HH, II 是四轮变换中的基本操作
      55            0 : inline void FF(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) {
      56            0 :     a += F(b, c, d) + x + ac;
      57            0 :     a = ROTATE_LEFT(a, s);
      58            0 :     a += b;
      59            0 : }
      60              : 
      61            0 : inline void GG(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) {
      62            0 :     a += G(b, c, d) + x + ac;
      63            0 :     a = ROTATE_LEFT(a, s);
      64            0 :     a += b;
      65            0 : }
      66              : 
      67            0 : inline void HH(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) {
      68            0 :     a += H(b, c, d) + x + ac;
      69            0 :     a = ROTATE_LEFT(a, s);
      70            0 :     a += b;
      71            0 : }
      72              : 
      73            0 : inline void II(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) {
      74            0 :     a += I(b, c, d) + x + ac;
      75            0 :     a = ROTATE_LEFT(a, s);
      76            0 :     a += b;
      77            0 : }
      78              : 
      79            0 : void NSLBMD5::init() {
      80            0 :     finalized = false;
      81              :     
      82              :     // 初始化状态为标准值
      83            0 :     count[0] = count[1] = 0;
      84              :     // 初始化MD5缓冲区
      85            0 :     state[0] = 0x67452301;
      86            0 :     state[NSLB_MD5_STATE1] = 0xEFCDAB89;
      87            0 :     state[NSLB_MD5_STATE2] = 0x98BADCFE;
      88            0 :     state[NSLB_MD5_STATE3] = 0x10325476;
      89            0 : }
      90              : 
      91            0 : NSLBMD5::NSLBMD5() {
      92            0 :     init();
      93            0 : }
      94              : 
      95            0 : NSLBMD5::NSLBMD5(const std::string& text) {
      96            0 :     init();
      97            0 :     update(text.c_str(), text.length());
      98            0 :     finalize();
      99            0 : }
     100              : 
     101              : // 解码字节数组为32位整数数组 - 改进实现,避免使用强制类型转换
     102            0 : void NSLBMD5::decode(uint32_t output[], const uint8_t input[], size_t len) {
     103              :     // 使用std::memcpy安全地复制内存,避免强制类型转换
     104            0 :     size_t num_ints = len / NSLB_MD5_4;
     105            0 :     for (size_t i = 0; i < num_ints; ++i) {
     106            0 :         (void)memcpy_s(&output[i], sizeof(uint32_t), &input[i * NSLB_MD5_4], sizeof(uint32_t));
     107              :     }
     108            0 : }
     109              : 
     110              : 
     111              : // 编码32位整数数组为字节数组
     112            0 : void NSLBMD5::encode(unsigned char output[], const uint32_t input[], size_t len) {
     113            0 :     for (size_t i = 0, j = 0; j < len; i++, j += NSLB_MD5_4) {
     114            0 :         output[j] = input[i] & 0xff;
     115            0 :         output[j + NSLB_MD5_STATE1] = (input[i] >> NSLB_MD5_8) & 0xff;
     116            0 :         output[j + NSLB_MD5_STATE2] = (input[i] >> NSLB_MD5_16) & 0xff;
     117            0 :         output[j + NSLB_MD5_STATE3] = (input[i] >> NSLB_MD5_24) & 0xff;
     118              :     }
     119            0 : }
     120              : 
     121              : /**
     122              :  * 背景:标准的MD5算法,主要功能是64字节处理
     123              :  * 参考文献:RFC 1321: The MD5 Message-Digest Algorithm
     124              :  * 作者:Ron Rivest
     125              :  * 发布日期:1992年4月
     126              :  */
     127            0 : void NSLBMD5::update(const unsigned char input[], size_t length) {
     128              :     // 计算还需要填充多少字节才能达到64字节的倍数
     129            0 :     unsigned int index = count[0] / NSLB_MD5ENCODE_COUNT % NSLB_MD5_TOTAL;
     130              : 
     131              :     // 更新消息长度
     132            0 :     if ((count[0] += (length << NSLB_MD5_COUNTLEN3)) < (length << NSLB_MD5_COUNTLEN3)) {
     133            0 :         count[1]++;
     134              :     }
     135            0 :     count[1] += (length >> NSLB_MD5_COUNTLEN29);
     136              : 
     137              :     // 计算需要处理多少个完整的64字节块
     138            0 :     unsigned int firstpart = NSLB_MD5_TOTAL - index;
     139              :     unsigned int i;
     140              : 
     141              :     // 处理消息的第一部分(如果有)
     142            0 :     if (length >= firstpart) {
     143            0 :         (void)memcpy_s(&buffer[index], firstpart, input, firstpart);
     144            0 :         transform(buffer);
     145              : 
     146              :         // 处理剩余的64字节块
     147            0 :         for (i = firstpart; i + (NSLB_MD5_TOTAL - 1) < length; i += NSLB_MD5_TOTAL)
     148            0 :             transform(&input[i]);
     149              : 
     150            0 :         index = 0;
     151              :     } else {
     152            0 :         i = 0;
     153              :     }
     154              : 
     155              :     // 存储剩余的字节
     156            0 :     (void)memcpy_s(&buffer[index], length - i, &input[i], length - i);
     157            0 : }
     158              : 
     159            0 : void NSLBMD5::update(const char input[], size_t length) {
     160              :     // 转换为uint8_t指针,使用标准C++转换
     161            0 :     update(reinterpret_cast<const uint8_t*>(input), length);
     162            0 : }
     163              : 
     164              : /**
     165              :  * 背景:标准的MD5算法,主要功能是MD5算法的核心变换函数,处理一个64字节的块
     166              :  * 参考文献:RFC 1321: The MD5 Message-Digest Algorithm
     167              :  * 作者:Ron Rivest
     168              :  * 发布日期:1992年4月
     169              : */
     170            0 : void NSLBMD5::transform(const unsigned char block[64]) {
     171            0 :     uint32_t a = state[0], b = state[NSLB_MD5_STATE1], c = state[NSLB_MD5_STATE2], d = state[NSLB_MD5_STATE3], x[NSLB_MD5_16];
     172              : 
     173            0 :     decode(x, block, NSLB_MD5_TOTAL);
     174              : 
     175              :     // 第一轮
     176            0 :     FF(a, b, c, d, x[ 0],  NSLB_MD5_7, 0xd76aa478);
     177            0 :     FF(d, a, b, c, x[NSLB_MD5_HASH1], NSLB_MD5_12, 0xe8c7b756);
     178            0 :     FF(c, d, a, b, x[NSLB_MD5_HASH2], NSLB_MD5_17, 0x242070db);
     179            0 :     FF(b, c, d, a, x[NSLB_MD5_HASH3], NSLB_MD5_22, 0xc1bdceee);
     180            0 :     FF(a, b, c, d, x[NSLB_MD5_HASH4],  NSLB_MD5_7, 0xf57c0faf);
     181            0 :     FF(d, a, b, c, x[NSLB_MD5_HASH5], NSLB_MD5_12, 0x4787c62a);
     182            0 :     FF(c, d, a, b, x[NSLB_MD5_HASH6], NSLB_MD5_17, 0xa8304613);
     183            0 :     FF(b, c, d, a, x[NSLB_MD5_HASH7], NSLB_MD5_22, 0xfd469501);
     184            0 :     FF(a, b, c, d, x[NSLB_MD5_HASH8], NSLB_MD5_7, 0x698098d8);
     185            0 :     FF(d, a, b, c, x[NSLB_MD5_HASH9], NSLB_MD5_12, 0x8b44f7af);
     186            0 :     FF(c, d, a, b, x[NSLB_MD5_HASH10], NSLB_MD5_17, 0xffff5bb1);
     187            0 :     FF(b, c, d, a, x[NSLB_MD5_HASH11], NSLB_MD5_22, 0x895cd7be);
     188            0 :     FF(a, b, c, d, x[NSLB_MD5_HASH12],  NSLB_MD5_7, 0x6b901122);
     189            0 :     FF(d, a, b, c, x[NSLB_MD5_HASH13], NSLB_MD5_12, 0xfd987193);
     190            0 :     FF(c, d, a, b, x[NSLB_MD5_HASH14], NSLB_MD5_17, 0xa679438e);
     191            0 :     FF(b, c, d, a, x[NSLB_MD5_HASH15], NSLB_MD5_22, 0x49b40821);
     192              : 
     193              :     // 第二轮
     194            0 :     GG(a, b, c, d, x[NSLB_MD5_HASH1],  NSLB_MD5_5, 0xf61e2562);
     195            0 :     GG(d, a, b, c, x[NSLB_MD5_HASH6],  NSLB_MD5_9, 0xc040b340);
     196            0 :     GG(c, d, a, b, x[NSLB_MD5_HASH11], NSLB_MD5_14, 0x265e5a51);
     197            0 :     GG(b, c, d, a, x[ 0], NSLB_MD5_20, 0xe9b6c7aa);
     198            0 :     GG(a, b, c, d, x[NSLB_MD5_HASH5],  NSLB_MD5_5, 0xd62f105d);
     199            0 :     GG(d, a, b, c, x[NSLB_MD5_HASH10],  NSLB_MD5_9, 0x02441453);
     200            0 :     GG(c, d, a, b, x[NSLB_MD5_HASH15], NSLB_MD5_14, 0xd8a1e681);
     201            0 :     GG(b, c, d, a, x[NSLB_MD5_HASH4], NSLB_MD5_20, 0xe7d3fbc8);
     202            0 :     GG(a, b, c, d, x[NSLB_MD5_HASH9],  NSLB_MD5_5, 0x21e1cde6);
     203            0 :     GG(d, a, b, c, x[NSLB_MD5_HASH14],  NSLB_MD5_9, 0xc33707d6);
     204            0 :     GG(c, d, a, b, x[NSLB_MD5_HASH3], NSLB_MD5_14, 0xf4d50d87);
     205            0 :     GG(b, c, d, a, x[NSLB_MD5_HASH8], NSLB_MD5_20, 0x455a14ed);
     206            0 :     GG(a, b, c, d, x[NSLB_MD5_HASH13],  NSLB_MD5_5, 0xa9e3e905);
     207            0 :     GG(d, a, b, c, x[NSLB_MD5_HASH2],  NSLB_MD5_9, 0xfcefa3f8);
     208            0 :     GG(c, d, a, b, x[NSLB_MD5_HASH7], NSLB_MD5_14, 0x676f02d9);
     209            0 :     GG(b, c, d, a, x[NSLB_MD5_HASH12], NSLB_MD5_20, 0x8d2a4c8a);
     210              : 
     211              :     // 第三轮
     212            0 :     HH(a, b, c, d, x[NSLB_MD5_HASH5],  NSLB_MD5_4, 0xfffa3942);
     213            0 :     HH(d, a, b, c, x[NSLB_MD5_HASH8], NSLB_MD5_11, 0x8771f681);
     214            0 :     HH(c, d, a, b, x[NSLB_MD5_HASH11], NSLB_MD5_16, 0x6d9d6122);
     215            0 :     HH(b, c, d, a, x[NSLB_MD5_HASH14], NSLB_MD5_23, 0xfde5380c);
     216            0 :     HH(a, b, c, d, x[NSLB_MD5_HASH1],  NSLB_MD5_4, 0xa4beea44);
     217            0 :     HH(d, a, b, c, x[NSLB_MD5_HASH4], NSLB_MD5_11, 0x4bdecfa9);
     218            0 :     HH(c, d, a, b, x[NSLB_MD5_HASH7], NSLB_MD5_16, 0xf6bb4b60);
     219            0 :     HH(b, c, d, a, x[NSLB_MD5_HASH10], NSLB_MD5_23, 0xbebfbc70);
     220            0 :     HH(a, b, c, d, x[NSLB_MD5_HASH13],  NSLB_MD5_4, 0x289b7ec6);
     221            0 :     HH(d, a, b, c, x[ 0], NSLB_MD5_11, 0xeaa127fa);
     222            0 :     HH(c, d, a, b, x[NSLB_MD5_HASH3], NSLB_MD5_16, 0xd4ef3085);
     223            0 :     HH(b, c, d, a, x[NSLB_MD5_HASH6], NSLB_MD5_23, 0x04881d05);
     224            0 :     HH(a, b, c, d, x[NSLB_MD5_HASH9],  NSLB_MD5_4, 0xd9d4d039);
     225            0 :     HH(d, a, b, c, x[NSLB_MD5_HASH12], NSLB_MD5_11, 0xe6db99e5);
     226            0 :     HH(c, d, a, b, x[NSLB_MD5_HASH15], NSLB_MD5_16, 0x1fa27cf8);
     227            0 :     HH(b, c, d, a, x[NSLB_MD5_HASH2], NSLB_MD5_23, 0xc4ac5665);
     228              : 
     229              :     // 第四轮
     230            0 :     II(a, b, c, d, x[ 0],  NSLB_MD5_6, 0xf4292244);
     231            0 :     II(d, a, b, c, x[NSLB_MD5_HASH7], NSLB_MD5_10, 0x432aff97);
     232            0 :     II(c, d, a, b, x[NSLB_MD5_HASH14], NSLB_MD5_15, 0xab9423a7);
     233            0 :     II(b, c, d, a, x[NSLB_MD5_HASH5], NSLB_MD5_21, 0xfc93a039);
     234            0 :     II(a, b, c, d, x[NSLB_MD5_HASH12],  NSLB_MD5_6, 0x655b59c3);
     235            0 :     II(d, a, b, c, x[NSLB_MD5_HASH3], NSLB_MD5_10, 0x8f0ccc92);
     236            0 :     II(c, d, a, b, x[NSLB_MD5_HASH10], NSLB_MD5_15, 0xffeff47d);
     237            0 :     II(b, c, d, a, x[NSLB_MD5_HASH1], NSLB_MD5_21, 0x85845dd1);
     238            0 :     II(a, b, c, d, x[NSLB_MD5_HASH8],  NSLB_MD5_6, 0x6fa87e4f);
     239            0 :     II(d, a, b, c, x[NSLB_MD5_HASH15], NSLB_MD5_10, 0xfe2ce6e0);
     240            0 :     II(c, d, a, b, x[NSLB_MD5_HASH6], NSLB_MD5_15, 0xa3014314);
     241            0 :     II(b, c, d, a, x[NSLB_MD5_HASH13], NSLB_MD5_21, 0x4e0811a1);
     242            0 :     II(a, b, c, d, x[NSLB_MD5_HASH4],  NSLB_MD5_6, 0xf7537e82);
     243            0 :     II(d, a, b, c, x[NSLB_MD5_HASH11], NSLB_MD5_10, 0xbd3af235);
     244            0 :     II(c, d, a, b, x[NSLB_MD5_HASH2], NSLB_MD5_15, 0x2ad7d2bb);
     245            0 :     II(b, c, d, a, x[NSLB_MD5_HASH9], NSLB_MD5_21, 0xeb86d391);
     246              : 
     247              :     // 将变换结果添加到当前状态
     248            0 :     state[0] += a;
     249            0 :     state[NSLB_MD5_STATE1] += b;
     250            0 :     state[NSLB_MD5_STATE2] += c;
     251            0 :     state[NSLB_MD5_STATE3] += d;
     252              : 
     253              :     // 清除缓冲区
     254            0 :     (void)memset_s(x, sizeof(x), 0, sizeof(x));
     255            0 : }
     256              : 
     257              : // 完成MD5计算
     258            0 : NSLBMD5& NSLBMD5::finalize() {
     259              :     static unsigned char bits[8];
     260              :     unsigned int index, padLen;
     261              : 
     262              :     // 存储消息长度
     263            0 :     encode(bits, count, NSLB_MD5ENCODE_COUNT);
     264              : 
     265              :     // 填充消息使其长度为56字节的倍数
     266            0 :     index = count[0] / NSLB_MD5ENCODE_COUNT % NSLB_MD5_TOTAL;
     267            0 :     padLen = (index < NSLB_MD5_56) ? (NSLB_MD5_56 - index) : (NSLB_MD5_120 - index);
     268            0 :     update(PADDING, padLen);
     269              : 
     270              :     // 附加长度
     271            0 :     update(bits, NSLB_MD5ENCODE_COUNT);
     272              : 
     273              :     // 存储状态到digest
     274            0 :     encode(digest, state, NSLB_MD5_DIGEST);
     275              : 
     276              :     // 清除敏感信息
     277            0 :     (void)memset_s(buffer, sizeof(buffer), 0, sizeof(buffer));
     278            0 :     (void)memset_s(count, sizeof(count), 0, sizeof(count));
     279              : 
     280            0 :     finalized = true;
     281            0 :     return *this;
     282              : }
     283              : 
     284              : // 转换为十六进制字符串
     285            0 : std::string NSLBMD5::hexdigest() const {
     286            0 :     if (!finalized)
     287            0 :         return "";
     288            0 :     std::string result;
     289            0 :     result.reserve(NSLB_MD5_RESERVE);
     290              :     
     291            0 :     for (unsigned int i = 0; i < NSLB_MD5_DIGEST; i++) {
     292              :         // 手动转换为十六进制字符
     293            0 :         uint8_t byte = digest[i];
     294            0 :         result.push_back(HEX[(byte >> NSLB_MD5_STATE4) & 0xF]);
     295            0 :         result.push_back(HEX[byte & 0xF]);
     296              :     }
     297              : 
     298            0 :     return result;
     299            0 : }
     300              : 
     301            0 : std::ostream& operator<<(std::ostream& out, NSLBMD5 md5) {
     302            0 :     return out << md5.hexdigest();
     303              : }
     304              : 
     305            0 : std::string nslb_md5(const std::string str) {
     306            0 :     NSLBMD5 md5 = NSLBMD5(str);
     307            0 :     return md5.hexdigest();
     308              : }
     309              : 
     310              : // 计算NslbDpRankInfo结构体向量的MD5
     311            0 : void NSLBMD5::calculateRankInfoMd5(const std::vector<NslbDpRankInfo>& rankInfo, uint8_t commMd5Sum[16]) {
     312            0 :     NSLBMD5 md5;
     313              :     
     314              :     // 遍历向量中的每个结构体元素
     315            0 :     for (const auto& info : rankInfo) {
     316              :         // 将结构体转换为字节数组并更新MD5
     317            0 :         md5.update(reinterpret_cast<const unsigned char*>(&info), sizeof(NslbDpRankInfo));
     318              :     }
     319              :     
     320              :     // 完成MD5计算
     321            0 :     md5.finalize();
     322              :     
     323              :     // 将结果复制到输出数组
     324            0 :     (void)memcpy_s(commMd5Sum, NSLB_MD5_DIGEST, md5.digest, NSLB_MD5_DIGEST);
     325            0 : }
     326              : 
     327              : // 新增:计算TableFourRankInfo结构体向量的MD5
     328            0 : void NSLBMD5::calculateTableFourRankInfoMd5(const std::vector<TableFourRankInfo>& rankInfo, uint8_t commMd5Sum[16]) {
     329            0 :     NSLBMD5 md5;
     330              :     
     331              :     // 遍历向量中的每个结构体元素
     332            0 :     for (const auto& info : rankInfo) {
     333              :         // 将结构体转换为字节数组并更新MD5
     334            0 :         md5.update(reinterpret_cast<const uint8_t*>(&info), sizeof(TableFourRankInfo));
     335              :     }
     336              :     
     337              :     // 完成MD5计算
     338            0 :     md5.finalize();
     339              :     // 将结果复制到输出数组
     340            0 :     (void)memcpy_s(commMd5Sum, NSLB_MD5_DIGEST, md5.digest, NSLB_MD5_DIGEST);
     341            0 : }
     342              : 
     343              : // 将MD5值转换为字符串
     344            0 : std::string NSLBMD5::md5ToString(const uint8_t md5[16]) {
     345            0 :     std::string result;
     346            0 :     result.reserve(NSLB_MD5_RESERVE);
     347              :     
     348            0 :     for (unsigned int i = 0; i < NSLB_MD5_DIGEST; i++) {
     349              :         // 手动转换为十六进制字符
     350            0 :         uint8_t byte = md5[i];
     351            0 :         result.push_back(HEX[(byte >> NSLB_MD5_STATE1) & 0xF]);
     352            0 :         result.push_back(HEX[byte & 0xF]);
     353              :     }
     354              :     
     355            0 :     return result;
     356            0 : }
     357              : 
     358              : }
        

Generated by: LCOV version 2.0-1