SM4密码算法(附源码)

SM4是我们自己国家的一个分组密码算法,是国家密码管理局于2012年发布的。网址戳→_→:http://www.cnnic.NET.cn/jscx/mixbz/sm4/

具体的密码标准和算法官方有非常详尽的PDF文档以供查阅,戳→_→:http://218.241.108.63/wiki/images/2/22/SM4%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E7%AE%97%E6%B3%95.pdf

算法的源码实现官方也有相应的示例源码,戳→_→:

http://218.241.108.63/wiki/index.PHP/File:Sm2_sm3_sm4_c%E8%AF%AD%E8%A8%80%E5%AE%9E%E7%8E%B0.zip

先说说啥是分组密码算法:

分组密码算法——国际DES、国产SM4

分组密码就是将明文数据按固定长度进行分组,然后在同一密钥控制下逐组进行加密,从而将各个明文分组变换成一个等长的密文分组的密码。其中二进制明文分组的长度称为该分组密码的分组规模。

SM4密码算法的整体结构图如下:


SM4的源代码中存在如下几个函数:

void sm4_setkey_enc(sm4_context *ctx,unsigned char key[16])

void sm4_setkey_dec(sm4_context *ctx,unsigned char key[16])

void sm4_crypt_ecb( sm4_context *ctx,int mode,int length, unsigned char *input,unsigned char *output)

void sm4_crypt_cbc( sm4_context *ctx,int mode,int length,unsigned char iv[16],unsigned char *input,unsigned char *output )

static void sm4_setkey( unsigned long SK[32], unsigned char key[16] )

还有一个非常重要的结构体:sm4_context

typedef struct

{

    int mode;                   /*!<  encrypt/decrypt   */

    unsigned long sk[32];       /*!<  SM4 subkeys       */

}

sm4_context;

先说结构体:

sm4_context结构体中的Mode控制是加密还是解密,sk则表示子密钥,也称作轮密钥。

 

第一个函数: void sm4_setkey_enc(sm4_context *ctx,unsigned char key[16])

这个函数是用来设置加密密钥的,一个参数分别为sm4_context *ctx和一个key。

其内部会调用static void sm4_setkey( unsigned long SK[32], unsigned char key[16] )函数

这个函数是用来设置密钥的,这个函数内部会对当前传入的主密钥进行32轮的迭代,每次迭代的轮密钥都被存放到ctx结构中的sk数组中。

void sm4_setkey_dec(sm4_context *ctx,unsigned char key[16])函数就是解密函数,过程为上述过程的逆序过程。

第二个函数:void sm4_crypt_ecb( sm4_context *ctx,int mode,int length, unsigned char 

这个函数的作用是使用ecb模式(ECB(Electronic Codebook,电码本)模式是分组密码的一种最基本的工作模式。同样,sm4_crypt_cbc函数则是使用的CBC模式,也就是分组链接模式)来对内容进行加密,内部也是一个循环,根据length的长度来进行循环,每次循环都调用sm4_one_round进行加密或者解密,到底是加密还是解密,主要是根据第二个参数Mode来进行决定。

以上就是整个SM4算法的函数简介,运用这些函数接口,我们不需要知道内部的具体实现,就可以使用sm4加密算法来对我们的数据进行加解密,十分的方便。


/*测试代码* SM4/SMS4 algorithm test programme* 2012-4-21*/#include <string.h>
#include <stdio.h>
#include "sm4.h"int main()
{unsigned char key[16] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};unsigned char input[16] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};unsigned char output[16];sm4_context ctx;unsigned long i;//encrypt standard testing vectorsm4_setkey_enc(&ctx,key);sm4_crypt_ecb(&ctx,1,16,input,output);for(i=0;i<16;i++)printf("%02x ", output[i]);printf("\n");//decrypt testingsm4_setkey_dec(&ctx,key);sm4_crypt_ecb(&ctx,0,16,output,output);for(i=0;i<16;i++)printf("%02x ", output[i]);printf("\n");return 0;
}

/*** \file sm4.h*/
#ifndef XYSSL_SM4_H
#define XYSSL_SM4_H#define SM4_ENCRYPT     1
#define SM4_DECRYPT     0/*** \brief          SM4 context structure*/
typedef struct
{int mode;                   /*!<  encrypt/decrypt   */unsigned long sk[32];       /*!<  SM4 subkeys       */
}
sm4_context;#ifdef __cplusplus
extern "C" {
#endif/*** \brief          SM4 key schedule (128-bit, encryption)** \param ctx      SM4 context to be initialized* \param key      16-byte secret key*/
void sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] );/*** \brief          SM4 key schedule (128-bit, decryption)** \param ctx      SM4 context to be initialized* \param key      16-byte secret key*/
void sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] );/*** \brief          SM4-ECB block encryption/decryption* \param ctx      SM4 context* \param mode     SM4_ENCRYPT or SM4_DECRYPT* \param length   length of the input data* \param input    input block* \param output   output block*/
void sm4_crypt_ecb( sm4_context *ctx,int mode,int length,unsigned char *input,unsigned char *output);#ifdef __cplusplus
}
#endif#endif /* sm4.h */
/** SM4 Encryption alogrithm (SMS4 algorithm)* GM/T 0002-2012 Chinese National Standard ref:http://www.oscca.gov.cn/ * thanks to Xyssl* thnaks and refers to http://hi.baidu.com/numax/blog/item/80addfefddfb93e4cf1b3e61.html* author:goldboar* email:goldboar@163.com* 2012-4-20*/// Test vector 1
// plain: 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
// key:   01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
// 	   round key and temp computing result:
// 	   rk[ 0] = f12186f9 X[ 0] = 27fad345
// 		   rk[ 1] = 41662b61 X[ 1] = a18b4cb2
// 		   rk[ 2] = 5a6ab19a X[ 2] = 11c1e22a
// 		   rk[ 3] = 7ba92077 X[ 3] = cc13e2ee
// 		   rk[ 4] = 367360f4 X[ 4] = f87c5bd5
// 		   rk[ 5] = 776a0c61 X[ 5] = 33220757
// 		   rk[ 6] = b6bb89b3 X[ 6] = 77f4c297
// 		   rk[ 7] = 24763151 X[ 7] = 7a96f2eb
// 		   rk[ 8] = a520307c X[ 8] = 27dac07f
// 		   rk[ 9] = b7584dbd X[ 9] = 42dd0f19
// 		   rk[10] = c30753ed X[10] = b8a5da02
// 		   rk[11] = 7ee55b57 X[11] = 907127fa
// 		   rk[12] = 6988608c X[12] = 8b952b83
// 		   rk[13] = 30d895b7 X[13] = d42b7c59
// 		   rk[14] = 44ba14af X[14] = 2ffc5831
// 		   rk[15] = 104495a1 X[15] = f69e6888
// 		   rk[16] = d120b428 X[16] = af2432c4
// 		   rk[17] = 73b55fa3 X[17] = ed1ec85e
// 		   rk[18] = cc874966 X[18] = 55a3ba22
// 		   rk[19] = 92244439 X[19] = 124b18aa
// 		   rk[20] = e89e641f X[20] = 6ae7725f
// 		   rk[21] = 98ca015a X[21] = f4cba1f9
// 		   rk[22] = c7159060 X[22] = 1dcdfa10
// 		   rk[23] = 99e1fd2e X[23] = 2ff60603
// 		   rk[24] = b79bd80c X[24] = eff24fdc
// 		   rk[25] = 1d2115b0 X[25] = 6fe46b75
// 		   rk[26] = 0e228aeb X[26] = 893450ad
// 		   rk[27] = f1780c81 X[27] = 7b938f4c
// 		   rk[28] = 428d3654 X[28] = 536e4246
// 		   rk[29] = 62293496 X[29] = 86b3e94f
// 		   rk[30] = 01cf72e5 X[30] = d206965e
// 		   rk[31] = 9124a012 X[31] = 681edf34
// cypher: 68 1e df 34 d2 06 96 5e 86 b3 e9 4f 53 6e 42 46
// 		
// test vector 2
// the same key and plain 1000000 times coumpting 
// plain:  01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
// key:    01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
// cypher: 59 52 98 c7 c6 fd 27 1f 04 02 f8 04 c3 3d 3f 66#include "sm4.h"
#include <string.h>
#include <stdio.h>/** 32-bit integer manipulation macros (big endian)*/
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i)                             \
{                                                       \(n) = ( (unsigned long) (b)[(i)    ] << 24 )        \| ( (unsigned long) (b)[(i) + 1] << 16 )        \| ( (unsigned long) (b)[(i) + 2] <<  8 )        \| ( (unsigned long) (b)[(i) + 3]       );       \
}
#endif#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i)                             \
{                                                       \(b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \(b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \(b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \(b)[(i) + 3] = (unsigned char) ( (n)       );       \
}
#endif/**rotate shift left marco definition**/
#define  SHL(x,n) (((x) & 0xFFFFFFFF) << n)
#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }/** Expanded SM4 S-boxes/* Sbox table: 8bits input convert to 8 bits output*/static const unsigned char SboxTable[16][16] = 
{
{0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05},
{0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99},
{0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62},
{0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6},
{0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8},
{0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35},
{0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87},
{0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e},
{0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1},
{0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3},
{0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f},
{0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51},
{0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8},
{0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0},
{0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84},
{0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48}
};/* System parameter */
static const unsigned long FK[4] = {0xa3b1bac6,0x56aa3350,0x677d9197,0xb27022dc};/* fixed parameter */
static const unsigned long CK[32] =
{
0x00070e15,0x1c232a31,0x383f464d,0x545b6269,
0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,
0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,
0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,
0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,
0x30373e45,0x4c535a61,0x686f767d,0x848b9299,
0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,
0x10171e25,0x2c333a41,0x484f565d,0x646b7279
};/** private function:* look up in SboxTable and get the related value.* args:    [in] inch: 0x00~0xFF (8 bits unsigned value).*/
static unsigned char sm4Sbox(unsigned char inch)
{unsigned char *pTable = (unsigned char *)SboxTable;unsigned char retVal = (unsigned char)(pTable[inch]);return retVal;
}/** private F(Lt) function:* "T algorithm" == "L algorithm" + "t algorithm".* args:    [in] a: a is a 32 bits unsigned value;* return: c: c is calculated with line algorithm "L" and nonline algorithm "t"*/
static unsigned long sm4Lt(unsigned long ka)
{unsigned long bb = 0;unsigned long c = 0;unsigned char a[4];unsigned char b[4];PUT_ULONG_BE(ka,a,0)b[0] = sm4Sbox(a[0]);b[1] = sm4Sbox(a[1]);b[2] = sm4Sbox(a[2]);b[3] = sm4Sbox(a[3]);GET_ULONG_BE(bb,b,0)c =bb^(ROTL(bb, 2))^(ROTL(bb, 10))^(ROTL(bb, 18))^(ROTL(bb, 24));return c;
}/** private F function:* Calculating and getting encryption/decryption contents.* args:    [in] x0: original contents;* args:    [in] x1: original contents;* args:    [in] x2: original contents;* args:    [in] x3: original contents;* args:    [in] rk: encryption/decryption key;* return the contents of encryption/decryption contents.*/
static unsigned long sm4F(unsigned long x0, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long rk)
{return (x0^sm4Lt(x1^x2^x3^rk));
}/* private function:* Calculating round encryption key.* args:    [in] a: a is a 32 bits unsigned value;* return: sk[i]: i{0,1,2,3,...31}.*/
static unsigned long sm4CalciRK(unsigned long ka)
{unsigned long bb = 0;unsigned long rk = 0;unsigned char a[4];unsigned char b[4];PUT_ULONG_BE(ka,a,0)b[0] = sm4Sbox(a[0]);b[1] = sm4Sbox(a[1]);b[2] = sm4Sbox(a[2]);b[3] = sm4Sbox(a[3]);GET_ULONG_BE(bb,b,0)rk = bb^(ROTL(bb, 13))^(ROTL(bb, 23));return rk;
}static void sm4_setkey( unsigned long SK[32], unsigned char key[16] )
{unsigned long MK[4];unsigned long k[36];unsigned long i = 0;GET_ULONG_BE( MK[0], key, 0 );GET_ULONG_BE( MK[1], key, 4 );GET_ULONG_BE( MK[2], key, 8 );GET_ULONG_BE( MK[3], key, 12 );k[0] = MK[0]^FK[0];k[1] = MK[1]^FK[1];k[2] = MK[2]^FK[2];k[3] = MK[3]^FK[3];for(; i<32; i++){k[i+4] = k[i] ^ (sm4CalciRK(k[i+1]^k[i+2]^k[i+3]^CK[i]));SK[i] = k[i+4];}}/** SM4 standard one round processing**/
static void sm4_one_round( unsigned long sk[32],unsigned char input[16],unsigned char output[16] )
{unsigned long i = 0;unsigned long ulbuf[36];memset(ulbuf, 0, sizeof(ulbuf));GET_ULONG_BE( ulbuf[0], input, 0 )GET_ULONG_BE( ulbuf[1], input, 4 )GET_ULONG_BE( ulbuf[2], input, 8 )GET_ULONG_BE( ulbuf[3], input, 12 )while(i<32){ulbuf[i+4] = sm4F(ulbuf[i], ulbuf[i+1], ulbuf[i+2], ulbuf[i+3], sk[i]);
// #ifdef _DEBUG
//        	printf("rk(%02d) = 0x%08x,  X(%02d) = 0x%08x \n",i,sk[i], i, ulbuf[i+4] );
// #endifi++;}PUT_ULONG_BE(ulbuf[35],output,0);PUT_ULONG_BE(ulbuf[34],output,4);PUT_ULONG_BE(ulbuf[33],output,8);PUT_ULONG_BE(ulbuf[32],output,12);
}/** SM4 key schedule (128-bit, encryption)*/
void sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] )
{ctx->mode = SM4_ENCRYPT;sm4_setkey( ctx->sk, key );
}/** SM4 key schedule (128-bit, decryption)*/
void sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] )
{int i;ctx->mode = SM4_ENCRYPT;sm4_setkey( ctx->sk, key );for( i = 0; i < 16; i ++ ){SWAP( ctx->sk[ i ], ctx->sk[ 31-i] );}
}/** SM4-ECB block encryption/decryption*/void sm4_crypt_ecb( sm4_context *ctx,int mode,int length,unsigned char *input,unsigned char *output)
{while( length > 0 ){sm4_one_round( ctx->sk, input, output );input  += 16;output += 16;length -= 16;}}


转载于:https://www.cnblogs.com/mao0504/p/6188111.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/394822.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux隐藏apache信息,Apache防盗链和隐藏版本信息-linux-centos运维

有需要服务器方面的需求和咨询&#xff0c;可以联系博主 QQ 7271895一、防盗链二、隐藏版本信息实验要求&#xff1a;三台虚拟机分别是&#xff1a;linux和两台windows虚拟机&#xff0c;linux虚拟机为服务器&#xff0c;Windows7-1为客户端&#xff0c;Windows7-2为盗链端。实…

led显示屏控制卡接线图解_Led显示屏出现花屏是什么原因

Led显示屏已经成为现在人们推广的一种形式了&#xff0c;很多地方都是离不开led显示屏的使用的。由于Led显示屏的五彩绚烂&#xff0c;也更加吸引人们的眼球。不过在使用过程中&#xff0c;也会遇到Led显示屏花屏的情况。那么&#xff0c;Led显示屏出现花屏是什么原因呢?下面伟…

Android OkHttp完全解析 是时候来了解OkHttp了

Android OkHttp完全解析 是时候来了解OkHttp了 标签&#xff1a; AndroidOkHttp2015-08-24 15:36 316254人阅读 评论(306) 收藏 举报分类&#xff1a;【android 进阶之路】&#xff08;67&#xff09; 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载…

c盘users的用户名怎么改_做完这几个操作,我从C盘中清理了30G垃圾文件

信息技术土著&#xff0c;一个有营养的公众号有个存在学说&#xff0c;比说一个人的身体某部位&#xff0c;如果不痛&#xff0c;你很少感觉他是存在的&#xff0c;但是某一天&#xff0c;因为某种原因&#xff0c;它突然很痛了&#xff0c;然后你每时每刻都会感觉到它的存在了…

MongoDB在Linux下常用优化设置

MongoDB在Linux下常用优化设置以下是一些MongoDB推荐的常用优化设置。在生产环境下选取合适的参数值&#xff0c;例如预读值和默认文件描述符数目等&#xff0c;会对系统性能有很大的影响。1、关闭数据库文件的 atime禁止系统对文件的访问时间更新会有效提高文件读取的性能。这…

ipconfig没有显示ip_TCP/IP 协议修复网络问题

nternet 在 TCP/IP 协议上工作&#xff0c;如果 TCP/IP 协议堆栈在 Windows 或任何其他操作系统(例如 Linux 或 MacOS)中无法正常工作&#xff0c;则您的 Internet 连接会出现问题。解决 Internet 问题的最佳方法是重置 TCP/IP 堆栈设置。如何在 Windows 中重置 TCP/IP 堆栈&am…

mysql-linux64,Linux64下mysql安装和开辟

1.1地址&#xff1a;http://www.mysql.com/downloads/mysql/5.5.html&#xff03;downloads版本&#xff1a;5.1.68平台&#xff1a;linux generalGeneric Linux (glibc 2.3) (x86&#xff0c; 64-bit)&#xff0c; RPM Package版本&#xff1a;MySQL Server(MySQL-server-5.1.…

python截图识别文字_用百度ocr+微信截图实现文字识别

作用&#xff1a;将图片中的文字识别出来 一、调用微信截图dll控件 将微信截图插件复制到项目文件&#xff0c;使用ctypes加载&#xff08;胶水语言就是给力&#xff09; def capture(): try: dll ctypes.cdll.LoadLibrary(PrScrn.dll) except Exception: print("Dll loa…

【用jQuery来判断浏览器的类型】及【javascript获取用户ip地址】

用jQuery来判断浏览器的类型,主要是使用$.browser这个工具类,使用方法: $.browser.[浏览器关键字] //谷歌浏览器、360浏览器等其他一些浏览器&#xff0c;没有专门的判断 function appInfo() {var bro $.browser;var binfo "";if (bro.msie) {binfo "Micr…

linux mv 递归拷贝,奇技淫巧 - 给Linux中的cp和mv命令中添加进度条的高级拷贝

GNU cp和GNU mv命令用于在GNU/Linux操作系统中复制和移动文件和目录。这两个命令缺少的一个特性是它们不显示任何进度条。如果复制一个大文件或目录&#xff0c;您就不知道完成复制过程需要多长时间&#xff0c;也不知道复制的数据所占的百分比。还有您将看不到当前正在复制哪个…

【洛谷P1966】火柴排队

两列排序后将编号一一对应 归并排序求逆序对 &#xff08;每一次交换就去掉一个逆序对&#xff09; 1 #include<cstdio>2 #include<cstring>3 #include<algorithm>4 #define ll long long5 using namespace std;6 const int N100100;7 const ll P99999997;8 …

Alan Walker MV 合辑01 by defender

Alan Walker MV合辑 出来啦&#xff01; 百度网盘下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/10WSool70XBe_8tJOae8V-w 提取码&#xff1a;uckq 地址查看Microsoft Onedrive Download Address:  BE DELETED Google Drive Download Address&#xff1a; …

在unity中设置多种怪物数据_Unity可编程渲染管线(SRP)系列(三)——光照(单通道 正向渲染)...

本文重点:1、漫反射着色2、支持方向光、点光源和聚光灯3、每帧允许16个可见光源4、每个对象最多计算四个像素光和四个顶点光这是涵盖Unity可编写脚本的渲染管线的教程系列的第三部分。这次&#xff0c;我们将通过一个Drawcall为每个对象最多着色8个灯光来增加对漫反射光照的支持…

蛋清打发奶油状

在做蛋糕、冰淇凌、面包之类的时候往往都需要奶油状蛋清&#xff0c;让蛋糕、面包更蓬松&#xff0c;冰激凌也可以使用其当做奶油来用。用料 鸡蛋4个 根据用量选择盐(只做冰激凌用奶油放)5g(根据蛋量)白醋(可以不放&#xff0c;根据喜好)5g(根据蛋量)白砂糖40g(分三次放)根据…

hql可以使用distinct吗_输送食品可以使用白色PVC输送带吗?

食品&#xff0c;是给人们吃到肚子里的&#xff0c;因此不管在加工环节、制造环节还是其他环节&#xff0c;都需要做好食品的安全问题。根据不同的食品&#xff0c;其制造的环境也不同&#xff0c;所使用到的食品输送带的材质也是不一样的&#xff0c;这些是需要根据输送的食品…

htc one m7 linux驱动,HTC One M7官方RUU固件包(可救砖)

在网上找了找关于HTC One M7 (801e)的官方ruu固件包还不多&#xff0c;找了一些&#xff0c;不过有些不能下载&#xff0c;在这里整理了几款可以下载的官方ruu包&#xff0c;这些包都是官方原版的&#xff0c;都是支持线刷的&#xff0c;大家可以下载下来备用了&#xff0c;也可…

c语言fmin最小公倍数,matlab小函数

8种机械键盘轴体对比本人程序员&#xff0c;要买一个写代码的键盘&#xff0c;请问红轴和茶轴怎么选&#xff1f;(记得按字母序索引)矩阵向量化操作A(:)拉成一个向量 ($a_{11},a_{21},…$)&#xff0c;注意先列后行repmat用途&#xff1a;创建由小型矩阵重复组合成的矩阵&#…

报表系统的雄心

这周有朋自远方来&#xff0c;聊了对报表工具的看法&#xff0c;因此专门写篇文章来谈谈报表系统的未来。 笔者知道不可能有十全十美的报表系统&#xff0c;毕竟任何一个行业和企业受自身客观环境的限制&#xff0c;但表哥嘛&#xff0c;总要有点理想和追求&#xff0c;就好比到…

vuefullcalendar怎么判断切换上下月_房间太多、楼上楼下,终极解决家里wifi信号无缝切换问题...

相信不少人有我一样的烦恼&#xff0c;房间太多&#xff0c;或者楼上楼下&#xff0c;家里的wifi信号总是不能无缝切换。路由器放在配电箱&#xff0c;除了客厅信号不错外&#xff0c;一旦到了其他房间&#xff0c;掉线、网速慢等问题让人很苦恼。特别是和小伙伴一起玩游戏一边…

手把手教你 Spark 性能调优

0、背景 集群部分 spark 任务执行很慢&#xff0c;且经常出错&#xff0c;参数改来改去怎么都无法优化其性能和解决频繁随机报错的问题。 看了下任务的历史运行情况&#xff0c;平均时间 3h 左右&#xff0c;而且极其不稳定&#xff0c;偶尔还会报错&#xff1a; 1、优化思路 任…