SM3密码杂凑算法

本文参考国标文件GB/T 32905——2016,重点在于对示例的计算。


1 范围

本标准规定了SM3密码杂凑算法的计算方法和计算步骤,并给出了运算示例。
本标准适用于商用密码应用中的数字签名和验证、消息认证码的生成与验证以及随机数的生成,可满足多种密码应用的安全需求。


2 术语和定义

下列术语和定义适用于本文将。

2.1 比特串 bit string

具有0或1值的二进制数字序列。

2.2 大端 big-endian

数组在内存中的一种表示格式,规定左边为高有效位,右边为低有效位。即数的高阶字节放在存储器的低地址,数的低阶字节放在存储器的高地址。

2.3 消息 message

任意有限长度的比特串,本标准中消息作为杂凑算法的输入数据。

2.4 杂凑值 hash value

杂凑算法作用于一条消息时输出的消息摘要(比特串)。

2.5 字 word

长度为32比特的组(串)。


3 符号

下列符号适用于本文件。
A B C D E F G H ABCDEFGH ABCDEFGH:8个字寄存器或它们的值的串连
B ( i ) B_{(i)} B(i):第 i i i个消息分组
C F CF CF:压缩函数
F F j {FF}_j FFj:布尔函数,随 j j j的变化取不同的表达式
G G j {GG}_j GGj:布尔函数,随 j j j的变化取不同的表达式
I V IV IV:初始值,用于确定压缩函数寄存器的初态
P 0 P_0 P0:压缩函数中的置换函数
P 1 P_1 P1:消息扩展中的置换函数
T j T_j Tj:算法常量,随 j j j的变化取不同的值
m m m:消息
m ′ {m}' m:填充后的消息
m o d mod mod:模运算
n n n:消息分组个数
∧ \wedge :32比特与运算
∨ \vee :32比特或运算
⊕ \oplus :32比特异或运算
¬ \neg ¬:32比特非运算
+ + +:mod 2 32 2^{32} 232比特算术加运算
< < < k <<<k <<<k:32比特循环左移 k k k比特运算
← \gets :左向赋值运算符


4 常数与函数

4.1 初始值

$IV=$7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e

4.2 常量

T j = {  79cc4519  0 ≤ j ≤ 15  7a879d8a  16 ≤ j ≤ 63 T_j=\begin{cases} & \text{ 79cc4519 } \quad 0\le j\le 15 \\ & \text{ 7a879d8a } \quad 16\le j \le 63 \end{cases} Tj={ 79cc4519 0j15 7a879d8a 16j63

4.3 布尔函数

F F j ( X , Y , Z ) = { X ⊕ Y ⊕ Z 0 ≤ j ≤ 15 ( X ∧ Y ) ∨ ( X ∧ Z ) ∨ ( Y ∧ Z ) 16 ≤ j ≤ 63 {FF}_j(X,Y,Z)=\begin{cases} &{X \oplus Y \oplus Z} \quad 0 \le j\le15 \\ &{(X \wedge Y)\vee(X \wedge Z)\vee(Y \wedge Z)} \quad 16 \le j \le 63 \end{cases} FFj(X,Y,Z)={XYZ0j15(XY)(XZ)(YZ)16j63
G G j ( X , Y , Z ) = { X ⊕ Y ⊕ Z 0 ≤ j ≤ 15 ( X ∧ Y ) ∨ ( ¬ X ∧ Z ) 16 ≤ j ≤ 63 {GG}_j(X,Y,Z)=\begin{cases} &{X \oplus Y \oplus Z} \quad 0 \le j\le15 \\ &{(X \wedge Y)\vee(\neg X \wedge Z)} \quad 16 \le j \le 63 \end{cases} GGj(X,Y,Z)={XYZ0j15(XY)(¬XZ)16j63
其中 X , Y , Z X,Y,Z X,Y,Z为字。


例: X = X= X= 7380166F, Y = Y= Y= 4914B2B9, Z = Z= Z= 172442D7
0 ≤ j ≤ 15 0 \le j \le 15 0j15时:
F F j ( X , Y , Z ) = X ⊕ Y ⊕ Z = {FF}_j(X,Y,Z)=X \oplus Y \oplus Z= FFj(X,Y,Z)=XYZ= (7380166F) ⊕ \oplus (4914B2B9) ⊕ \oplus (172442D7) = = = 2DB0E601
G G j ( X , Y , Z ) = X ⊕ Y ⊕ Z = {GG}_j(X,Y,Z)=X \oplus Y \oplus Z= GGj(X,Y,Z)=XYZ= (7380166F) ⊕ \oplus (4914B2B9) ⊕ \oplus (172442D7) = = = 2DB0E601
16 ≤ j ≤ 63 16 \le j \le 63 16j63时:
F F j ( X , Y , Z ) = ( X ∧ Y ) ∨ ( X ∧ Z ) ∨ ( Y ∧ Z ) = ( 7380166 F ∧ 4914 B 2 B 9 ) ∨ ( 7380166 F ∧ 172442 D 7 ) ∨ ( 4914 B 2 B 9 ∧ 172442 D 7 ) = ( 41001229 ) ∨ ( 13000247 ) ∨ ( 01040291 ) = 530412 F F {FF}_j(X,Y,Z)={(X \wedge Y)\vee(X \wedge Z)\vee(Y \wedge Z)}={(7380166F \wedge 4914B2B9)\vee(7380166F \wedge 172442D7)\vee(4914B2B9 \wedge 172442D7)}=(41001229)\vee (13000247) \vee (01040291)= 530412FF FFj(X,Y,Z)=(XY)(XZ)(YZ)=(7380166F4914B2B9)(7380166F172442D7)(4914B2B9172442D7)=(41001229)(13000247)(01040291)=530412FF
G G j ( X , Y , Z ) = ( X ∧ Y ) ∨ ( ¬ X ∧ Z ) = ( 7380166 F ∧ 4914 B 2 B 9 ) ∨ ( ¬ 7380166 F ∧ 172442 D 7 ) = ( 41001229 ) ∨ ( 8 C 7 F E 990 ∧ 172442 D 7 ) = ( 41001229 ) ∨ ( 04244090 ) = 452452 B 9 {GG}_j(X,Y,Z)={(X \wedge Y)\vee(\neg X \wedge Z)}={(7380166F \wedge 4914B2B9)\vee(\neg 7380166F \wedge 172442D7)}=(41001229) \vee(8C7FE990 \wedge 172442D7)=(41001229) \vee(04244090)=452452B9 GGj(X,Y,Z)=(XY)(¬XZ)=(7380166F4914B2B9)(¬7380166F172442D7)=(41001229)(8C7FE990172442D7)=(41001229)(04244090)=452452B9

4.4 置换函数

P 0 ( X ) = X ⊕ ( X < < < 9 ) ⊕ ( X < < < 17 ) P_0(X)=X \oplus (X<<<9) \oplus (X<<<17) P0(X)=X(X<<<9)(X<<<17)
P 1 ( X ) = X ⊕ ( X < < < 15 ) ⊕ ( X < < < 23 ) P_1(X)=X \oplus (X<<<15) \oplus (X<<<23) P1(X)=X(X<<<15)(X<<<23)
其中 X X X为字。


例:
P 0 ( 7380166 F ) = 7380166 F ⊕ ( 002 C D E E 7 ) ⊕ ( 2 C D E E 700 ) = 5 F 722 F 88 P_0(7380166F)=7380166F \oplus (002CDEE7) \oplus (2CDEE700)=5F722F88 P0(7380166F)=7380166F(002CDEE7)(2CDEE700)=5F722F88
P 1 ( 7380166 F ) = 7380166 F ⊕ ( 0 B 37 B 9 C 0 ) ⊕ ( 37 B 9 C 00 B ) = 4 F 0 E 6 F A 4 P_1(7380166F)=7380166F \oplus (0B37B9C0) \oplus (37B9C00B)=4F0E6FA4 P1(7380166F)=7380166F(0B37B9C0)(37B9C00B)=4F0E6FA4


5 算法描述

5.1 概述

SM3密码杂凑算法的输入为长度为 l ( l < 2 64 ) l(l<2^{64}) l(l<264)比特的消息 m m m,经过填充、迭代压缩,生成杂凑值,杂凑值输出长度为256比特。

5.2 填充

假设消息 m m m的长度为 l l l比特,则首先将比特“1”添加到消息的末尾,再添加 k k k个“0”, k k k是满足 l + 1 + k ≡ 448 ( m o d 512 ) l+1+k\equiv 448(mod \quad 512) l+1+k448(mod512)的最小的非负整数。然后添加一个64位比特串,该比特串是长度 l l l的二进制表示。填充后的消息 m ′ {m}' m的比特长度为512的倍数。
例如:对消息:01100001 01100010 01100011,其长度 l = 24 l=24 l=24,经填充得到比特串:
在这里插入图片描述
在这里插入图片描述

5.3 迭代压缩

5.3.1 迭代过程

将填充后的消息 m ′ {m}' m按512比特进行分组: m ′ = B ( 0 ) B ( 1 ) ⋅ ⋅ ⋅ B ( n − 1 ) {m}'=B^{(0)}B^{(1)}\cdot \cdot \cdot B^{(n-1)} m=B(0)B(1)B(n1),其中 n = ( l + k + 65 ) / 512 n=(l+k+65)/512 n=(l+k+65)/512
m ′ {m}' m按下列方式迭代:
在这里插入图片描述
其中 C F CF CF是压缩函数, V ( 0 ) V^{(0)} V(0)为256比特初始值 I V IV IV B ( i ) B^{(i)} B(i)为填充后的消息分组,迭代压缩结果为 V ( n ) V^{(n)} V(n)

5.3.2 消息扩展

将消息分组 B ( i ) B^{(i)} B(i)按以下方法扩展生成132个消息字 W 0 , W 1 , ⋅ ⋅ ⋅ W 67 , W 0 ′ , W 1 ′ , ⋅ ⋅ ⋅ W 63 ′ W_0,W_1,\cdot \cdot \cdot W_{67},{W_0}',{W_1}',\cdot \cdot \cdot {W_{63}}' W0,W1,W67,W0,W1,W63,用于压缩函数 C F CF CF
第一步,将消息分组 B ( i ) B^{(i)} B(i)划分为16个字 W 0 , W 1 , ⋅ ⋅ ⋅ W 15 W_0,W_1,\cdot \cdot \cdot W_{15} W0,W1,W15
第二步,
F O R j = 16 T o 67 FOR \quad j=16 \quad To \quad 67 FORj=16To67
W j ← P 1 ( W j − 16 ⊕ W j − 9 ⊕ ( W j − 3 < < < 15 ) ) ⊕ ( W j − 13 < < < 7 ) ⊕ W j − 6 E N D F O R \quad \quad W_j \gets P_1(W_{j-16}\oplus W_{j-9} \oplus (W_{j-3}<<<15))\oplus (W_{j-13}<<<7) \oplus W_{j-6} \quad ENDFOR WjP1(Wj16Wj9(Wj3<<<15))(Wj13<<<7)Wj6ENDFOR
第三步,
F O R j = 0 T O 63 FOR \quad j=0 \quad TO \quad 63 FORj=0TO63
W j ′ = W i ⊕ W i + 4 \quad \quad {W_j}'=W_i \oplus W_{i+4} Wj=WiWi+4
E N D F O R ENDFOR ENDFOR


例: B 0 = B^0= B0= 61626380 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000018
W 16 ← P 1 ( W 0 ⊕ W 7 ⊕ ( W 3 < < < 15 ) ) ⊕ ( W 3 < < < 7 ) ⊕ W 10 = P 1 ( 61626380 ) = 9092 E 200 W_{16} \gets P_1(W_0 \oplus W_7 \oplus (W_3<<<15)) \oplus (W_3<<<7) \oplus W_{10}=P_1(61626380)=9092E200 W16P1(W0W7(W3<<<15))(W3<<<7)W10=P1(61626380)=9092E200
其他依次类推。
W 0 ′ = W 0 ⊕ W 4 = 61626380 {W_0}'=W_0 \oplus W_4=61626380 W0=W0W4=61626380
其他依次类推。
在这里插入图片描述

5.3.3 压缩函数

A , B , C , D , E , F , G , H A,B,C,D,E,F,G,H A,B,C,D,E,F,G,H为字寄存器, S S 1 , S S 2 , T T 1 , T T 2 SS1,SS2,TT1,TT2 SS1,SS2,TT1,TT2为中间变量,压缩函数 V i + 1 = C F ( V ( i ) , B ( i ) ) , 0 ≤ i ≤ n − 1 V^{i+1}=CF(V^{(i)},B^{(i)}),0 \le i \le n-1 Vi+1=CF(V(i),B(i)),0in1。计算过程描述如下:
A B C D E F G H ← V ( i ) ABCDEFGH \gets V^{(i)} ABCDEFGHV(i)
F O R j = 0 T o 63 FOR \quad j=0 \quad To \quad 63 FORj=0To63
S S 1 ← ( ( A < < < 12 ) + E + ( T i < < < ( j m o d 32 ) ) ) < < < 7 \quad \quad SS1 \gets((A<<<12)+E+(T_i<<<(j\quad mod32)))<<<7 SS1((A<<<12)+E+(Ti<<<(jmod32)))<<<7
S S 2 ← S S 1 ⊕ ( A < < < 12 ) \quad \quad SS2 \gets SS1 \oplus (A<<<12) SS2SS1(A<<<12)
T T 1 ← F F i ( A , B , C ) + D + S S 2 + W i ′ \quad \quad TT1 \gets FF_i(A,B,C)+D+SS2+{W_i}' TT1FFi(A,B,C)+D+SS2+Wi
T T 2 ← G G i ( E , F , G ) + H + S S 1 + W i \quad \quad TT2 \gets GG_i(E,F,G)+H+SS1+W_i TT2GGi(E,F,G)+H+SS1+Wi
D ← C \quad \quad D \gets C DC
C ← B < < < 9 \quad \quad C\gets B<<<9 CB<<<9
B ← A \quad \quad B \gets A BA
A ← T T 1 \quad \quad A \gets TT1 ATT1
H ← G \quad \quad H \gets G HG
G ← F < < < 19 \quad \quad G \gets F<<<19 GF<<<19
F ← E \quad \quad F \gets E FE
E ← P 0 ( T T 2 ) \quad \quad E \gets P_0(TT2) EP0(TT2)
E N D F O R ENDFOR ENDFOR
V ( i + 1 ) ← A B C D E F G H ⊕ V ( i ) V^{(i+1)}\gets ABCDEFGH \oplus V^{(i)} V(i+1)ABCDEFGHV(i)
其中,字的存储为大端(big-endian),左边为高有效位,右边为低有效位。
+ + +为十六进制加法。


例: j = j= j= 0 I V = IV= IV= 7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e
S S 1 ← ( ( 7380166 f < < < 12 ) + a 96 f 30 b c + ( 79 c c 4519 < < < ( 0 m o d 32 ) ) ) < < < 7 = 51368692 SS1 \gets((7380166f<<<12)+a96f30bc+(79cc4519<<<(0\quad mod32)))<<<7=51368692 SS1((7380166f<<<12)+a96f30bc+(79cc4519<<<(0mod32)))<<<7=51368692
S S 2 ← S S 1 ⊕ ( A < < < 12 ) = 505071 A A SS2 \gets SS1 \oplus (A<<<12)=505071AA SS2SS1(A<<<12)=505071AA
T T 1 ← F F i ( A , B , C ) + D + S S 2 + W i ′ = 2 D B 0 E 601 + d a 8 a 0600 + 505071 A A + 61626380 = B 9 E D C 12 B TT1 \gets FF_i(A,B,C)+D+SS2+{W_i}'=2DB0E601 + da8a0600 + 505071AA + 61626380=B9EDC12B TT1FFi(A,B,C)+D+SS2+Wi=2DB0E601+da8a0600+505071AA+61626380=B9EDC12B
T T 2 ← G G i ( E , F , G ) + H + S S 1 + W i = 5 C D 3 E 65 B + b 0 f b 0 e 4 e + 51368692 + 61626380 = C 067 D E B B TT2 \gets GG_i(E,F,G)+H+SS1+W_i=5CD3E65B + b0fb0e4e + 51368692+ 61626380=C067DEBB TT2GGi(E,F,G)+H+SS1+Wi=5CD3E65B+b0fb0e4e+51368692+61626380=C067DEBB
D ← C = 172442 d 7 D \gets C=172442d7 DC=172442d7
C ← B < < < 9 = 29657292 C\gets B<<<9=29657292 CB<<<9=29657292
B ← A = 7380166 f B \gets A=7380166f BA=7380166f
A ← T T 1 = B 9 E D C 12 B A \gets TT1=B9EDC12B ATT1=B9EDC12B
H ← G = e 38 d e e 4 d H \gets G=e38dee4d HG=e38dee4d
G ← F < < < 19 = c 550 b 189 G \gets F<<<19=c550b189 GF<<<19=c550b189
F ← E = a 96 f 30 b c F \gets E=a96f30bc FE=a96f30bc
E ← P 0 ( T T 2 ) = B 2 A D 29 F 4 E \gets P_0(TT2)=B2AD29F4 EP0(TT2)=B2AD29F4
其他依次类推。
在这里插入图片描述

5.4 输出杂凑值

A B C D E F G H ← V ( n ) ABCDEFGH\gets V^{(n)} ABCDEFGHV(n)
输出256比特的杂凑值 y = A B C D E F G H y=ABCDEFGH y=ABCDEFGH


例:
V 1 = A B C D E F G H ⊕ V 0 = V^1=ABCDEFGH \oplus V^0= V1=ABCDEFGHV0= 66C7F0F4 62EEEDD9 D1F2D46B DC10E4E2 4167C487 5CF2F7A2 297DA02B 8F4BA8E0


6 完整代码

#ifndef _SM3_H_
#define _SM3_H_

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

const unsigned int IV[8] = {0x7380166F,0x4914B2B9,0x172442D7,0xDA8A0600,0xA96F30BC,0x163138AA,0xE38DEE4D,0xB0FB0E4E};

const unsigned int T[64] = {0x79CC4519,0x79CC4519,0x79CC4519,0x79CC4519,0x79CC4519,0x79CC4519,0x79CC4519,0x79CC4519,
                            0x79CC4519,0x79CC4519,0x79CC4519,0x79CC4519,0x79CC4519,0x79CC4519,0x79CC4519,0x79CC4519,
                            0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,
                            0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,
                            0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,
                            0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,
                            0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,
                            0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A,0x7A879D8A};

#endif
#include "sm3.h"

unsigned int FF(unsigned int X,unsigned int Y,unsigned int Z,int j);//布尔函数FF
unsigned int GG(unsigned int X,unsigned int Y,unsigned int Z,int j);//布尔函数GG
unsigned int move(unsigned int data , int length);
unsigned int P0(unsigned int X);
unsigned int P1(unsigned int X);
int PaddingNum(long long l);
unsigned int* inputPadding(char ch[]);
unsigned int * MessagePadding(unsigned int * B);
unsigned int * IteratveCompression(char ch[]);

unsigned int FF(unsigned int X,unsigned int Y,unsigned int Z,int j)
{
    if(0<=j && j<=15)
    {
        return X^Y^Z;
    }
    else if(16<=j && j<=63)
    {
        return (X&Y)|(X&Z)|(Y&Z);
    }
}

unsigned int GG(unsigned int X,unsigned int Y,unsigned int Z,int j)
{
    if(0<=j && j<=15)
    {
        return X^Y^Z;
    }
    else if(16<=j && j<=63)
    {
        return (X&Y)|(~X&Z);
    }
}

unsigned int move(unsigned int data , int length)
{
    unsigned int result = 0;
    result = (data << length) ^ (data >> (32-length));
    return result;
}

unsigned int P0(unsigned int X)
{
    return X^move(X,9)^move(X,17);
}

unsigned int P1(unsigned int X)
{
    return X^move(X,15)^move(X,23);
}

int PaddingNum(long long l)
{
    int k=-1,i=0;
    while (k<0)
    {
        k = 512*i+447-l;
        i++;
        if(k>=0)
            break;
    }   
    return k;
}

unsigned int* inputPadding(char m[])
{
    long long l = strlen(m)*8;    //输入的消息的位数
    int k=PaddingNum(l);
    int len = (l+1+k+64)/32;//填充后的信息   int类型的个数
    unsigned int *paddedInput = (unsigned int *)malloc(len*sizeof(unsigned int));
    memset(paddedInput,0,len*4);    //设初值为0
    //将原消息放到扩展信息中
    for (int i = 0; i < l/8; i++)
    {
        *(paddedInput+(i/4)) ^= *(m+i)<<(24-(i%4)*8);
    }
    //补充0x80
    *(paddedInput+l/32) ^= 0x80<<(24-((l/8)%4)*8);
    //在尾部填充长度l
    *(paddedInput+len-1) = l;
    return paddedInput;
}

unsigned int * MessagePadding(unsigned int * B)
{
    unsigned static int W[132] = {0};
    for(int i=0;i<16;i++)
    {
        W[i] = *(B+i);
    }
    for(int i=16;i<68;i++)
    {
        W[i]=P1(W[i-16]^W[i-9]^move(W[i-3],15))^move(W[i-13],7)^W[i-6];
    }
    for(int i=0;i<64;i++)
    {
        W[68+i] = W[i]^W[i+4];
    }
    return W;
}

unsigned int * IteratveCompression(char m[])
{
    long long l = strlen(m)*8;    //输入的消息的位数
    int k=PaddingNum(l);
    int len = (l+1+k+64)/32;//填充后的信息   int类型的个数
    unsigned int * paddedInput = inputPadding(m);
    unsigned static int V[8] = {0};
    V[0] = IV[0];
    V[1] = IV[1];
    V[2] = IV[2];
    V[3] = IV[3];
    V[4] = IV[4];
    V[5] = IV[5];
    V[6] = IV[6];
    V[7] = IV[7];
    unsigned int A,B,C,D,E,F,G,H,SS1,SS2,TT1,TT2;

    unsigned int Bmes[16] = {0};
    for(int i=0;i<len/16;i++)
    {   
        //每个分组都要对ABCDEFGH赋初值
        A=V[0];B=V[1];C=V[2];D=V[3];E=V[4];F=V[5];G=V[6];H=V[7];
        for(int j=0;j<16;j++)
        {
            Bmes[j] = *(paddedInput+16*i+j);
        }
        unsigned int *W = MessagePadding(Bmes);
        for(int j=0;j<64;j++)
        {
            SS1 = move((move(A,12)+E+move(T[j],j%32)),7);
            SS2=SS1^move(A,12);
            TT1 = FF(A,B,C,j)+D+SS2+W[j+68];
            TT2 = GG(E,F,G,j)+H+SS1+W[j];
            D=C;
            C=move(B,9);
            B=A;
            A=TT1;
            H=G;
            G=move(F,19);
            F=E;
            E=P0(TT2);
        }
        V[0] = A^V[0];V[1] = B^V[1];V[2] = C^V[2];V[3] = D^V[3];
        V[4] = E^V[4];V[5] = F^V[5];V[6] = G^V[6];V[7] = H^V[7];
    }
    return V;
}

int main()
{
    char input[100]="abc";
    printf("输入的消息为:\n");
    for(int i=0;i<strlen(input);i++)
    {
        printf("%c",input[i]);
        if(i%4==3)
            printf(" ");
    }
    printf("\n输入消息的十六进制为:\n");
    for(int i=0;i<strlen(input);i++)
    {
        printf("%.2x",input[i]);
        if(i%4==3)
            printf(" ");
    }
    unsigned int *hash =  IteratveCompression(input);
    printf("\n所得的十六进制杂凑值为:\n");
    for(int i=0;i<8;i++)
    {
        printf("%.8x ",*(hash+i));
    }
    return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值