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: 95.8 % 191 183
Test Date: 2026-08-18 17:47:01 Functions: 91.7 % 24 22

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

Generated by: LCOV version 2.0-1