活动介绍

若依分离版登录页面怎么使用数据绑定选择按钮和实现 <el-radio-group v-model="roleType"> <el-radio label="1">管理员</el-radio> <el-radio label="2">教师</el-radio> <el-radio label="3">学生</el-radio> </el-radio-group>

时间: 2025-07-15 15:39:41 浏览: 7
<think>好的,我需要帮助用户解决在若依分离版中使用v-model实现el-radio-group的数据绑定的问题。首先,我需要回忆一下element-ui中el-radio-group的使用方法。记得在element-ui中,el-radio-group需要绑定v-model来管理选中的值,而每个el-radio通过label属性设置对应的值。用户提到若依分离版,应该和普通的Vue项目结构类似,可能是在使用Vue2和element-ui的组合。 接下来,用户需要示例代码和教程。我应该先提供一个基本的示例,展示如何在模板中使用el-radio-group和el-radio,并绑定v-model到数据属性。比如,在data中定义一个selected变量,初始值设为空字符串,然后在el-radio-group中用v-model绑定selected,每个el-radio的label属性设置不同的值,比如'option1'和'option2'。 然后,可能需要说明如何处理选项变化的事件。element-ui的el-radio-group支持change事件,用户可以通过@change来监听变化,并执行相应的方法。例如,定义一个handleChange方法,当选项变化时触发,打印出选中的值或者进行其他操作。 另外,用户可能需要动态生成选项的情况,比如从后端获取数据列表来渲染el-radio。这时候可以用v-for遍历数组,动态生成el-radio组件,每个选项的label绑定到item.value,显示的名称用item.label。例如,在data中定义一个options数组,包含value和label,然后在模板中用v-for循环生成el-radio。 还需要考虑表单验证的情况,如果el-radio-group放在el-form中,可能需要绑定prop和校验规则。这时候需要结合el-form-item的prop属性,以及在data中定义的rules规则,确保用户必须选择一个选项。 此外,用户可能想知道如何将选中的值提交到后端,这涉及到在提交表单时获取selected的值,并通过axios或其他HTTP库发送请求。这部分可能需要简要提及,但主要焦点应该在数据绑定和组件使用上。 最后,要注意若依框架可能有一些特定的配置或约定,比如API的调用方式或目录结构,但针对前端的el-radio-group的使用,应该和标准的element-ui用法一致。因此,示例代码不需要特别针对若依调整,除非有特殊的情况需要说明。 总结一下,回答的结构应该是先给出基本的示例代码,解释各个部分的作用,然后扩展说明动态选项、事件处理和表单验证,最后可能提供相关的注意事项或常见问题。需要确保代码语法正确,特别是Vue的模板部分和数据绑定,避免拼写错误,比如v-model是否正确绑定,label属性是否设置正确等。</think>在若依分离版中使用Vue+ElementUI实现单选按钮组的数据绑定,可通过以下步骤实现: ### 一、基础数据绑定示例 ```vue <template> <div> <el-radio-group v-model="selectedOption"> <el-radio label="option1">选项一</el-radio> <el-radio label="option2">选项二</el-radio> <el-radio label="option3">选项三</el-radio> </el-radio-group> <p>当前选择:{{ selectedOption }}</p> </div> </template> <script> export default { data() { return { selectedOption: 'option1' // 默认选中项 } } } </script> ``` 该示例中: 1. `v-model`双向绑定到`selectedOption`变量 2. 每个`el-radio`的`label`属性对应选项值 3. 默认值通过数据初始化设置[^1] ### 二、动态选项实现 ```vue <template> <el-radio-group v-model="dynamicSelected"> <el-radio v-for="item in options" :key="item.value" :label="item.value" >{{ item.label }}</el-radio> </el-radio-group> </template> <script> export default { data() { return { dynamicSelected: '', options: [ { value: 'A', label: '苹果' }, { value: 'B', label: '香蕉' }, { value: 'C', label: '橙子' } ] } } } </script> ``` ### 三、事件处理 ```vue <el-radio-group v-model="selectedOption" @change="handleChange" > <!-- 选项内容 --> </el-radio-group> <script> methods: { handleChange(value) { console.log('当前选中值:', value) // 可在此处添加业务逻辑 } } </script> ``` ### 四、表单验证集成 在el-form中使用时: ```vue <el-form :model="form" :rules="rules"> <el-form-item label="性别" prop="gender"> <el-radio-group v-model="form.gender"> <el-radio label="male">男</el-radio> <el-radio label="female">女</el-radio> </el-radio-group> </el-form-item> </el-form> <script> data() { return { form: { gender: '' }, rules: { gender: [ { required: true, message: '请选择性别', trigger: 'change' } ] } } } </script> ``` ### 五、注意事项 1. 若需要整数值类型,使用`:label="1"`数字绑定 2. 禁用状态可添加`disabled`属性 3. 按钮样式可添加`type="button"`属性 4. 若依框架中需注意API数据格式的匹配
阅读全文

相关推荐

接前面的回复,定制版PG12的sm3算法本身和pgbouncer 里添加的sm3的内容一致。pgbouncer 需根据情况做了一些调整。 定制版PG12的sm3算法为: #define GETU32(p) ((uint32)(p)[0]<<24|(uint32)(p)[1]<<16|(uint32)(p)[2]<<8|(uint32)(p)[3]) #define PUT32(p,v) ((p)[0]=(uint8)((v)>>24),(p)[1]=(uint8)((v)>>16),(p)[2]=(uint8)((v)>>8),(p)[3]=(uint8)(v)) /* 32bit data rotate left n bit */ #define ROL32(a,n) (((a)<<(n)) | (((a)&0xffffffff)>>(32-(n)))) /* base on SM3 Algorithm's function definition */ #define FF00(x,y,z) ((x) ^ (y) ^ (z)) #define FF16(x,y,z) (((x)&(y)) | ((x)&(z)) | ((y)&(z))) #define GG00(x,y,z) ((x) ^ (y) ^ (z)) #define GG16(x,y,z) (((x)&(y)) | ((~x)&(z))) #define P0(x) ((x) ^ ROL32((x),9) ^ ROL32((x),17)) #define P1(x) ((x) ^ ROL32((x),15) ^ ROL32((x),23)) /* constant quantity */ #define T00 0x79cc4519U #define T16 0x7a879d8aU #define K0 0x79cc4519U #define K1 0xf3988a32U #define K2 0xe7311465U #define K3 0xce6228cbU #define K4 0x9cc45197U #define K5 0x3988a32fU #define K6 0x7311465eU #define K7 0xe6228cbcU #define K8 0xcc451979U #define K9 0x988a32f3U #define K10 0x311465e7U #define K11 0x6228cbceU #define K12 0xc451979cU #define K13 0x88a32f39U #define K14 0x11465e73U #define K15 0x228cbce6U #define K16 0x9d8a7a87U #define K17 0x3b14f50fU #define K18 0x7629ea1eU #define K19 0xec53d43cU #define K20 0xd8a7a879U #define K21 0xb14f50f3U #define K22 0x629ea1e7U #define K23 0xc53d43ceU #define K24 0x8a7a879dU #define K25 0x14f50f3bU #define K26 0x29ea1e76U #define K27 0x53d43cecU #define K28 0xa7a879d8U #define K29 0x4f50f3b1U #define K30 0x9ea1e762U #define K31 0x3d43cec5U #define K32 0x7a879d8aU #define K33 0xf50f3b14U #define K34 0xea1e7629U #define K35 0xd43cec53U #define K36 0xa879d8a7U #define K37 0x50f3b14fU #define K38 0xa1e7629eU #define K39 0x43cec53dU #define K40 0x879d8a7aU #define K41 0x0f3b14f5U #define K42 0x1e7629eaU #define K43 0x3cec53d4U #define K44 0x79d8a7a8U #define K45 0xf3b14f50U #define K46 0xe7629ea1U #define K47 0xcec53d43U #define K48 0x9d8a7a87U #define K49 0x3b14f50fU #define K50 0x7629ea1eU #define K51 0xec53d43cU #define K52 0xd8a7a879U #define K53 0xb14f50f3U #define K54 0x629ea1e7U #define K55 0xc53d43ceU #define K56 0x8a7a879dU #define K57 0x14f50f3bU #define K58 0x29ea1e76U #define K59 0x53d43cecU #define K60 0xa7a879d8U #define K61 0x4f50f3b1U #define K62 0x9ea1e762U #define K63 0x3d43cec5U uint32 K[64] = { K0, K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K60, K61, K62, K63, }; static void sm3_init(sm3_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->digest[0] = 0x7380166F; ctx->digest[1] = 0x4914B2B9; ctx->digest[2] = 0x172442D7; ctx->digest[3] = 0xDA8A0600; ctx->digest[4] = 0xA96F30BC; ctx->digest[5] = 0x163138AA; ctx->digest[6] = 0xE38DEE4D; ctx->digest[7] = 0xB0FB0E4E; } static void sm3_compress_blocks(uint32_t digest[8], const unsigned char *data, size_t blocks) { uint32 A; uint32 B; uint32 C; uint32 D; uint32 E; uint32 F; uint32 G; uint32 H; uint32 W[68]; int j = 0; uint32 SS1, SS2, TT1, TT2; while (blocks--) { A = digest[0]; B = digest[1]; C = digest[2]; D = digest[3]; E = digest[4]; F = digest[5]; G = digest[6]; H = digest[7]; for (j = 0; j < 16; j++) { W[j] = GETU32(data + j*4); } for (j = 16; j < 68; j++) { W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15)) ^ ROL32(W[j -13], 7) ^ W[j - 6]; } for (j = 0; j < 16; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF00(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG00(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } for (j = 16; j < 64; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF16(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG16(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } digest[0] ^= A; digest[1] ^= B; digest[2] ^= C; digest[3] ^= D; digest[4] ^= E; digest[5] ^= F; digest[6] ^= G; digest[7] ^= H; data += 64; } } static void sm3_compress(uint32_t digest[8], const unsigned char block[64]) { return sm3_compress_blocks(digest, block, 1); } static void sm3_final(sm3_ctx *ctx, unsigned char *digest) { int i; ctx->block[ctx->num] = 0x80; if (ctx->num + 9 <= SM3_BLOCK_SIZE) { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9); } else { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1); sm3_compress(ctx->digest, ctx->block); memset(ctx->block, 0, SM3_BLOCK_SIZE - 8); } PUTU32(ctx->block + 56, ctx->nblocks >> 23); PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); sm3_compress(ctx->digest, ctx->block); for (i = 0; i < 8; i++) { PUTU32(digest + i*4, ctx->digest[i]); } } static void sm3_update(sm3_ctx *ctx, const unsigned char *data, size_t data_len) { size_t blocks; if (ctx->num) { unsigned int left = SM3_BLOCK_SIZE - ctx->num; if (data_len < left) { memcpy(ctx->block + ctx->num, data, data_len); ctx->num += data_len; return; } else { memcpy(ctx->block + ctx->num, data, left); sm3_compress_blocks(ctx->digest, ctx->block, 1); ctx->nblocks++; data += left; data_len -= left; } } blocks = data_len / SM3_BLOCK_SIZE; sm3_compress_blocks(ctx->digest, data, blocks); ctx->nblocks += blocks; data += SM3_BLOCK_SIZE * blocks; data_len -= SM3_BLOCK_SIZE * blocks; ctx->num = data_len; if (data_len) { memcpy(ctx->block, data, data_len); } } static void bytesToHex(uint8 b[32], char *s) { static const char *hex = "0123456789abcdef"; int q, w; for (q = 0, w = 0; q < 32; q++) { s[w++] = hex[(b[q] >> 4) & 0x0F]; s[w++] = hex[b[q] & 0x0F]; } s[w] = '\0'; } bool pg_sm3_hash(const void *buff, size_t len, char *hexsum) { uint8 sum[SM3_DIGEST_LENGTH]; sm3_ctx ctx; sm3_init(&ctx); sm3_update(&ctx, buff, len); sm3_final(&ctx, sum); bytesToHex(sum, hexsum); return true; } bool pg_sm3_encrypt(const char *passwd, const char* salt, size_t salt_len, char *buf) { size_t passwd_len = strlen(passwd); char *crypt_buf = malloc(passwd_len + salt_len + 1); bool ret; if (!crypt_buf) return false; memcpy(crypt_buf, passwd, passwd_len); memcpy(crypt_buf + passwd_len, salt, salt_len); strcpy(buf, "sm3"); ret = hg_sm3_hash(crypt_buf, passwd_len + salt_len, buf + 3); free(crypt_buf); return ret; } pgbouncer/lib/usual/crypto/sm3.h: #ifndef _USUAL_CRYPTO_SM3_H_ #define _USUAL_CRYPTO_SM3_H_ #include <usual/base.h> /** Block size for SM3 */ #define SM3_BLOCK_SIZE 64 /** Result length for SM3 */ #define SM3_DIGEST_LENGTH 32 #define SM3_SALT_LENGTH 4 /** SM3 state */ typedef struct sm3_ctx { uint32_t digest[8]; // 哈希值 uint64_t nblocks; // 总分块数 unsigned char block[64]; // 当前处理块 int num; // 缓冲区填充量 } sm3_ctx; void sm3_reset(sm3_ctx *ctx); void sm3_update(sm3_ctx *ctx, const void *data, unsigned len); void sm3_final(sm3_ctx *ctx, unsigned char *digest); #endif pgbouncer/lib/usual/crypto/sm3.c: #include <usual/crypto/sm3.h> #include <usual/crypto/digest.h> #define GETU32(p) ((uint32_t)(p)[0]<<24|(uint32_t)(p)[1]<<16|(uint32_t)(p)[2]<<8|(uint32_t)(p)[3]) #define PUT32(p,v) ((p)[0]=(uint8_t)((v)>>24),(p)[1]=(uint8_t)((v)>>16),(p)[2]=(uint8_t)((v)>>8),(p)[3]=(uint8_t)(v)) /* 32bit data rotate left n bit */ #define ROL32(a,n) (((a)<<(n)) | (((a)&0xffffffff)>>(32-(n)))) /* base on SM3 Algorithm's function definition */ #define FF00(x,y,z) ((x) ^ (y) ^ (z)) #define FF16(x,y,z) (((x)&(y)) | ((x)&(z)) | ((y)&(z))) #define GG00(x,y,z) ((x) ^ (y) ^ (z)) #define GG16(x,y,z) (((x)&(y)) | ((~x)&(z))) #define P0(x) ((x) ^ ROL32((x),9) ^ ROL32((x),17)) #define P1(x) ((x) ^ ROL32((x),15) ^ ROL32((x),23)) /* constant quantity */ #define T00 0x79cc4519U #define T16 0x7a879d8aU #define K0 0x79cc4519U #define K1 0xf3988a32U #define K2 0xe7311465U #define K3 0xce6228cbU #define K4 0x9cc45197U #define K5 0x3988a32fU #define K6 0x7311465eU #define K7 0xe6228cbcU #define K8 0xcc451979U #define K9 0x988a32f3U #define K10 0x311465e7U #define K11 0x6228cbceU #define K12 0xc451979cU #define K13 0x88a32f39U #define K14 0x11465e73U #define K15 0x228cbce6U #define K16 0x9d8a7a87U #define K17 0x3b14f50fU #define K18 0x7629ea1eU #define K19 0xec53d43cU #define K20 0xd8a7a879U #define K21 0xb14f50f3U #define K22 0x629ea1e7U #define K23 0xc53d43ceU #define K24 0x8a7a879dU #define K25 0x14f50f3bU #define K26 0x29ea1e76U #define K27 0x53d43cecU #define K28 0xa7a879d8U #define K29 0x4f50f3b1U #define K30 0x9ea1e762U #define K31 0x3d43cec5U #define K32 0x7a879d8aU #define K33 0xf50f3b14U #define K34 0xea1e7629U #define K35 0xd43cec53U #define K36 0xa879d8a7U #define K37 0x50f3b14fU #define K38 0xa1e7629eU #define K39 0x43cec53dU #define K40 0x879d8a7aU #define K41 0x0f3b14f5U #define K42 0x1e7629eaU #define K43 0x3cec53d4U #define K44 0x79d8a7a8U #define K45 0xf3b14f50U #define K46 0xe7629ea1U #define K47 0xcec53d43U #define K48 0x9d8a7a87U #define K49 0x3b14f50fU #define K50 0x7629ea1eU #define K51 0xec53d43cU #define K52 0xd8a7a879U #define K53 0xb14f50f3U #define K54 0x629ea1e7U #define K55 0xc53d43ceU #define K56 0x8a7a879dU #define K57 0x14f50f3bU #define K58 0x29ea1e76U #define K59 0x53d43cecU #define K60 0xa7a879d8U #define K61 0x4f50f3b1U #define K62 0x9ea1e762U #define K63 0x3d43cec5U uint32_t K[64] = { K0, K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K60, K61, K62, K63, }; static void sm3_compress_blocks(uint32_t digest[8], const unsigned char *data, size_t blocks) { uint32_t A; uint32_t B; uint32_t C; uint32_t D; uint32_t E; uint32_t F; uint32_t G; uint32_t H; uint32_t W[68]; int j = 0; uint32_t SS1, SS2, TT1, TT2; while (blocks--) { A = digest[0]; B = digest[1]; C = digest[2]; D = digest[3]; E = digest[4]; F = digest[5]; G = digest[6]; H = digest[7]; for (j = 0; j < 16; j++) { W[j] = GETU32(data + j*4); } for (j = 16; j < 68; j++) { W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15)) ^ ROL32(W[j - 13], 7) ^ W[j - 6]; } for (j = 0; j < 16; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF00(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG00(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } for (j = 16; j < 64; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF16(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG16(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } digest[0] ^= A; digest[1] ^= B; digest[2] ^= C; digest[3] ^= D; digest[4] ^= E; digest[5] ^= F; digest[6] ^= G; digest[7] ^= H; data += 64; } } static void sm3_compress(uint32_t digest[8], const unsigned char block[64]) { return sm3_compress_blocks(digest, block, 1); } /* * Public API. */ void sm3_reset(sm3_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->digest[0] = 0x7380166F; ctx->digest[1] = 0x4914B2B9; ctx->digest[2] = 0x172442D7; ctx->digest[3] = 0xDA8A0600; ctx->digest[4] = 0xA96F30BC; ctx->digest[5] = 0x163138AA; ctx->digest[6] = 0xE38DEE4D; ctx->digest[7] = 0xB0FB0E4E; } void sm3_update(sm3_ctx *ctx, const void *data, unsigned len) { size_t blocks; if (ctx->num) { unsigned int left = SM3_BLOCK_SIZE - ctx->num; if (len < left) { memcpy(ctx->block + ctx->num, data, len); ctx->num += len; return; } else { memcpy(ctx->block + ctx->num, data, left); sm3_compress_blocks(ctx->digest, ctx->block, 1); ctx->nblocks++; data += left; len -= left; } } blocks = len / SM3_BLOCK_SIZE; sm3_compress_blocks(ctx->digest, data, blocks); ctx->nblocks += blocks; data += SM3_BLOCK_SIZE * blocks; len -= SM3_BLOCK_SIZE * blocks; ctx->num = len; if (len) { memcpy(ctx->block, data, len); } } void sm3_final(sm3_ctx *ctx, unsigned char *digest) { int i; ctx->block[ctx->num] = 0x80; if (ctx->num + 9 <= SM3_BLOCK_SIZE) { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9); } else { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1); sm3_compress(ctx->digest, ctx->block); memset(ctx->block, 0, SM3_BLOCK_SIZE - 8); } PUTU32(ctx->block + 56, ctx->nblocks >> 23); PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); sm3_compress(ctx->digest, ctx->block); for (i = 0; i < 8; i++) { PUTU32(digest + i*4, ctx->digest[i]); } } /* * DigestInfo */ static const struct DigestInfo sm3 = { (DigestInitFunc *)sm3_reset, (DigestUpdateFunc *)sm3_update, (DigestFinalFunc *)sm3_final, sizeof(struct sm3_ctx), SM3_DIGEST_LENGTH, SM3_BLOCK_SIZE }; const struct DigestInfo *digest_SM3(void) { return &sm3; } 大致正确吗

这是 pgbouncer 1.12.0 的部分源码: pgbouncer/lib/usual/crypto/digest.h 里有部分内容: typedef void (DigestInitFunc)(void *ctx); typedef void (DigestUpdateFunc)(void *ctx, const void *, unsigned); typedef void (DigestFinalFunc)(void *ctx, uint8_t *); /** * Algoright info. */ struct DigestInfo { DigestInitFunc *init; DigestUpdateFunc *update; DigestFinalFunc *final; short state_len; short result_len; short block_len; }; pgbouncer/lib/usual/crypto/md5.h 里的内容: #ifndef _USUAL_CRYPTO_MD5_H_ #define _USUAL_CRYPTO_MD5_H_ #include <usual/base.h> /** Block length for MD5 */ #define MD5_BLOCK_LENGTH 64 /** Result length for MD5 */ #define MD5_DIGEST_LENGTH 16 /** MD5 state */ struct md5_ctx { uint64_t nbytes; uint32_t a, b, c, d; uint32_t buf[16]; }; /** Clean state */ void md5_reset(struct md5_ctx *ctx); /** Update state with more data */ void md5_update(struct md5_ctx *ctx, const void *data, unsigned int len); /** Get final result */ void md5_final(struct md5_ctx *ctx, uint8_t *dst); #endif pgbouncer/lib/usual/crypto/md5.c 里的内容: #include <usual/crypto/md5.h> #include <usual/crypto/digest.h> #include <usual/endian.h> #include <usual/bits.h> /* * Support functions. */ #define bufpos(ctx) ((ctx)->nbytes & (MD5_BLOCK_LENGTH - 1)) static inline void swap_words(uint32_t *w, int n) { #ifdef WORDS_BIGENDIAN for (; n > 0; w++, n--) *w = le32toh(*w); #endif } /* * MD5 core. */ #define F(X,Y,Z) ((X & Y) | ((~X) & Z)) #define G(X,Y,Z) ((X & Z) | (Y & (~Z))) #define H(X,Y,Z) (X ^ Y ^ Z) #define I(X,Y,Z) (Y ^ (X | (~Z))) #define OP(fn, a, b, c, d, k, s, T_i) \ a = b + rol32(a + fn(b, c, d) + X[k] + T_i, s) static void md5_mix(struct md5_ctx *ctx, const uint32_t *X) { uint32_t a, b, c, d; a = ctx->a; b = ctx->b; c = ctx->c; d = ctx->d; /* Round 1. */ OP(F, a, b, c, d, 0, 7, 0xd76aa478); OP(F, d, a, b, c, 1, 12, 0xe8c7b756); OP(F, c, d, a, b, 2, 17, 0x242070db); OP(F, b, c, d, a, 3, 22, 0xc1bdceee); OP(F, a, b, c, d, 4, 7, 0xf57c0faf); OP(F, d, a, b, c, 5, 12, 0x4787c62a); OP(F, c, d, a, b, 6, 17, 0xa8304613); OP(F, b, c, d, a, 7, 22, 0xfd469501); OP(F, a, b, c, d, 8, 7, 0x698098d8); OP(F, d, a, b, c, 9, 12, 0x8b44f7af); OP(F, c, d, a, b, 10, 17, 0xffff5bb1); OP(F, b, c, d, a, 11, 22, 0x895cd7be); OP(F, a, b, c, d, 12, 7, 0x6b901122); OP(F, d, a, b, c, 13, 12, 0xfd987193); OP(F, c, d, a, b, 14, 17, 0xa679438e); OP(F, b, c, d, a, 15, 22, 0x49b40821); /* Round 2. */ OP(G, a, b, c, d, 1, 5, 0xf61e2562); OP(G, d, a, b, c, 6, 9, 0xc040b340); OP(G, c, d, a, b, 11, 14, 0x265e5a51); OP(G, b, c, d, a, 0, 20, 0xe9b6c7aa); OP(G, a, b, c, d, 5, 5, 0xd62f105d); OP(G, d, a, b, c, 10, 9, 0x02441453); OP(G, c, d, a, b, 15, 14, 0xd8a1e681); OP(G, b, c, d, a, 4, 20, 0xe7d3fbc8); OP(G, a, b, c, d, 9, 5, 0x21e1cde6); OP(G, d, a, b, c, 14, 9, 0xc33707d6); OP(G, c, d, a, b, 3, 14, 0xf4d50d87); OP(G, b, c, d, a, 8, 20, 0x455a14ed); OP(G, a, b, c, d, 13, 5, 0xa9e3e905); OP(G, d, a, b, c, 2, 9, 0xfcefa3f8); OP(G, c, d, a, b, 7, 14, 0x676f02d9); OP(G, b, c, d, a, 12, 20, 0x8d2a4c8a); /* Round 3. */ OP(H, a, b, c, d, 5, 4, 0xfffa3942); OP(H, d, a, b, c, 8, 11, 0x8771f681); OP(H, c, d, a, b, 11, 16, 0x6d9d6122); OP(H, b, c, d, a, 14, 23, 0xfde5380c); OP(H, a, b, c, d, 1, 4, 0xa4beea44); OP(H, d, a, b, c, 4, 11, 0x4bdecfa9); OP(H, c, d, a, b, 7, 16, 0xf6bb4b60); OP(H, b, c, d, a, 10, 23, 0xbebfbc70); OP(H, a, b, c, d, 13, 4, 0x289b7ec6); OP(H, d, a, b, c, 0, 11, 0xeaa127fa); OP(H, c, d, a, b, 3, 16, 0xd4ef3085); OP(H, b, c, d, a, 6, 23, 0x04881d05); OP(H, a, b, c, d, 9, 4, 0xd9d4d039); OP(H, d, a, b, c, 12, 11, 0xe6db99e5); OP(H, c, d, a, b, 15, 16, 0x1fa27cf8); OP(H, b, c, d, a, 2, 23, 0xc4ac5665); /* Round 4. */ OP(I, a, b, c, d, 0, 6, 0xf4292244); OP(I, d, a, b, c, 7, 10, 0x432aff97); OP(I, c, d, a, b, 14, 15, 0xab9423a7); OP(I, b, c, d, a, 5, 21, 0xfc93a039); OP(I, a, b, c, d, 12, 6, 0x655b59c3); OP(I, d, a, b, c, 3, 10, 0x8f0ccc92); OP(I, c, d, a, b, 10, 15, 0xffeff47d); OP(I, b, c, d, a, 1, 21, 0x85845dd1); OP(I, a, b, c, d, 8, 6, 0x6fa87e4f); OP(I, d, a, b, c, 15, 10, 0xfe2ce6e0); OP(I, c, d, a, b, 6, 15, 0xa3014314); OP(I, b, c, d, a, 13, 21, 0x4e0811a1); OP(I, a, b, c, d, 4, 6, 0xf7537e82); OP(I, d, a, b, c, 11, 10, 0xbd3af235); OP(I, c, d, a, b, 2, 15, 0x2ad7d2bb); OP(I, b, c, d, a, 9, 21, 0xeb86d391); ctx->a += a; ctx->b += b; ctx->c += c; ctx->d += d; } /* * Public API. */ void md5_reset(struct md5_ctx *ctx) { ctx->nbytes = 0; ctx->a = 0x67452301; ctx->b = 0xefcdab89; ctx->c = 0x98badcfe; ctx->d = 0x10325476; } void md5_update(struct md5_ctx *ctx, const void *data, unsigned int len) { unsigned int n; const uint8_t *ptr = data; uint8_t *buf = (uint8_t *)ctx->buf; while (len > 0) { n = MD5_BLOCK_LENGTH - bufpos(ctx); if (n > len) n = len; memcpy(buf + bufpos(ctx), ptr, n); ptr += n; len -= n; ctx->nbytes += n; if (bufpos(ctx) == 0) { swap_words(ctx->buf, 16); md5_mix(ctx, ctx->buf); } } } void md5_final(struct md5_ctx *ctx, uint8_t *dst) { static const uint8_t padding[MD5_BLOCK_LENGTH] = { 0x80 }; uint64_t final_len = ctx->nbytes * 8; int pad_len, pos = bufpos(ctx); /* add padding */ pad_len = MD5_BLOCK_LENGTH - 8 - pos; if (pad_len <= 0) pad_len += MD5_BLOCK_LENGTH; md5_update(ctx, padding, pad_len); /* add length directly */ swap_words(ctx->buf, 14); ctx->buf[14] = final_len; ctx->buf[15] = final_len >> 32; /* final result */ md5_mix(ctx, ctx->buf); le32enc(dst + 0, ctx->a); le32enc(dst + 4, ctx->b); le32enc(dst + 8, ctx->c); le32enc(dst + 12, ctx->d); } /* * DigestInfo */ static const struct DigestInfo md5 = { (DigestInitFunc *)md5_reset, (DigestUpdateFunc *)md5_update, (DigestFinalFunc *)md5_final, sizeof(struct md5_ctx), MD5_DIGEST_LENGTH, MD5_BLOCK_LENGTH }; const struct DigestInfo *digest_MD5(void) { return &md5; } 原生pgbouncer不支持sm3,需要在pgbouncer 1.12.0 源码的基础上添加sm3支持。 在 pgbouncer/lib/usual/crypto/sm3.h 里添加: #ifndef _USUAL_CRYPTO_SM3_H_ #define _USUAL_CRYPTO_SM3_H_ #include <usual/base.h> /** Block size for SM3 */ #define SM3_BLOCK_SIZE 64 /** Result length for SM3 */ #define SM3_DIGEST_LENGTH 32 /** SM3 state */ struct sm3_ctx { uint32 digest[8]; // 哈希值 uint64 nblocks; // 总分块数 unsigned char block[64]; // 当前处理块 int num; // 缓冲区填充量 }; void sm3_reset(sm3_ctx *ctx); void sm3_update(sm3_ctx *ctx, const unsigned char *data, size_t data_len); void sm3_final(sm3_ctx *ctx, unsigned char *digest); #endif 在 pgbouncer/lib/usual/crypto/sm3.c 里添加: #include <usual/crypto/sm3.h> #include <usual/crypto/digest.h> #define GETU32(p) ((uint32)(p)[0]<<24|(uint32)(p)[1]<<16|(uint32)(p)[2]<<8|(uint32)(p)[3]) #define PUT32(p,v) ((p)[0]=(uint8)((v)>>24),(p)[1]=(uint8)((v)>>16),(p)[2]=(uint8)((v)>>8),(p)[3]=(uint8)(v)) /* 32bit data rotate left n bit */ #define ROL32(a,n) (((a)<<(n)) | (((a)&0xffffffff)>>(32-(n)))) /* base on SM3 Algorithm's function definition */ #define FF00(x,y,z) ((x) ^ (y) ^ (z)) #define FF16(x,y,z) (((x)&(y)) | ((x)&(z)) | ((y)&(z))) #define GG00(x,y,z) ((x) ^ (y) ^ (z)) #define GG16(x,y,z) (((x)&(y)) | ((~x)&(z))) #define P0(x) ((x) ^ ROL32((x),9) ^ ROL32((x),17)) #define P1(x) ((x) ^ ROL32((x),15) ^ ROL32((x),23)) /* constant quantity */ #define T00 0x79cc4519U #define T16 0x7a879d8aU #define K0 0x79cc4519U #define K1 0xf3988a32U #define K2 0xe7311465U #define K3 0xce6228cbU #define K4 0x9cc45197U #define K5 0x3988a32fU #define K6 0x7311465eU #define K7 0xe6228cbcU #define K8 0xcc451979U #define K9 0x988a32f3U #define K10 0x311465e7U #define K11 0x6228cbceU #define K12 0xc451979cU #define K13 0x88a32f39U #define K14 0x11465e73U #define K15 0x228cbce6U #define K16 0x9d8a7a87U #define K17 0x3b14f50fU #define K18 0x7629ea1eU #define K19 0xec53d43cU #define K20 0xd8a7a879U #define K21 0xb14f50f3U #define K22 0x629ea1e7U #define K23 0xc53d43ceU #define K24 0x8a7a879dU #define K25 0x14f50f3bU #define K26 0x29ea1e76U #define K27 0x53d43cecU #define K28 0xa7a879d8U #define K29 0x4f50f3b1U #define K30 0x9ea1e762U #define K31 0x3d43cec5U #define K32 0x7a879d8aU #define K33 0xf50f3b14U #define K34 0xea1e7629U #define K35 0xd43cec53U #define K36 0xa879d8a7U #define K37 0x50f3b14fU #define K38 0xa1e7629eU #define K39 0x43cec53dU #define K40 0x879d8a7aU #define K41 0x0f3b14f5U #define K42 0x1e7629eaU #define K43 0x3cec53d4U #define K44 0x79d8a7a8U #define K45 0xf3b14f50U #define K46 0xe7629ea1U #define K47 0xcec53d43U #define K48 0x9d8a7a87U #define K49 0x3b14f50fU #define K50 0x7629ea1eU #define K51 0xec53d43cU #define K52 0xd8a7a879U #define K53 0xb14f50f3U #define K54 0x629ea1e7U #define K55 0xc53d43ceU #define K56 0x8a7a879dU #define K57 0x14f50f3bU #define K58 0x29ea1e76U #define K59 0x53d43cecU #define K60 0xa7a879d8U #define K61 0x4f50f3b1U #define K62 0x9ea1e762U #define K63 0x3d43cec5U uint32 K[64] = { K0, K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K60, K61, K62, K63, }; static void sm3_compress_blocks(uint32_t digest[8], const unsigned char *data, size_t blocks) { uint32 A; uint32 B; uint32 C; uint32 D; uint32 E; uint32 F; uint32 G; uint32 H; uint32 W[68]; int j = 0; uint32 SS1, SS2, TT1, TT2; while (blocks--) { A = digest[0]; B = digest[1]; C = digest[2]; D = digest[3]; E = digest[4]; F = digest[5]; G = digest[6]; H = digest[7]; for (j = 0; j < 16; j++) { W[j] = GETU32(data + j*4); } for (j = 16; j < 68; j++) { W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15)) ^ ROL32(W[j -13], 7) ^ W[j - 6]; } for (j = 0; j < 16; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF00(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG00(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } for (j = 16; j < 64; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF16(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG16(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } digest[0] ^= A; digest[1] ^= B; digest[2] ^= C; digest[3] ^= D; digest[4] ^= E; digest[5] ^= F; digest[6] ^= G; digest[7] ^= H; data += 64; } } static void sm3_compress(uint32_t digest[8], const unsigned char block[64]) { return sm3_compress_blocks(digest, block, 1); } /* * Public API. */ void sm3_reset(sm3_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->digest[0] = 0x7380166F; ctx->digest[1] = 0x4914B2B9; ctx->digest[2] = 0x172442D7; ctx->digest[3] = 0xDA8A0600; ctx->digest[4] = 0xA96F30BC; ctx->digest[5] = 0x163138AA; ctx->digest[6] = 0xE38DEE4D; ctx->digest[7] = 0xB0FB0E4E; } void sm3_update(sm3_ctx *ctx, const unsigned char *data, size_t data_len) { size_t blocks; if (ctx->num) { unsigned int left = SM3_BLOCK_SIZE - ctx->num; if (data_len < left) { memcpy(ctx->block + ctx->num, data, data_len); ctx->num += data_len; return; } else { memcpy(ctx->block + ctx->num, data, left); sm3_compress_blocks(ctx->digest, ctx->block, 1); ctx->nblocks++; data += left; data_len -= left; } } blocks = data_len / SM3_BLOCK_SIZE; sm3_compress_blocks(ctx->digest, data, blocks); ctx->nblocks += blocks; data += SM3_BLOCK_SIZE * blocks; data_len -= SM3_BLOCK_SIZE * blocks; ctx->num = data_len; if (data_len) { memcpy(ctx->block, data, data_len); } } void sm3_final(sm3_ctx *ctx, unsigned char *digest) { int i; ctx->block[ctx->num] = 0x80; if (ctx->num + 9 <= SM3_BLOCK_SIZE) { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9); } else { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1); sm3_compress(ctx->digest, ctx->block); memset(ctx->block, 0, SM3_BLOCK_SIZE - 8); } PUTU32(ctx->block + 56, ctx->nblocks >> 23); PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); sm3_compress(ctx->digest, ctx->block); for (i = 0; i < 8; i++) { PUTU32(digest + i*4, ctx->digest[i]); } } /* * DigestInfo */ static const struct DigestInfo sm3 = { (DigestInitFunc *)sm3_reset, (DigestUpdateFunc *)sm3_update, (DigestFinalFunc *)sm3_final, sizeof(struct sm3_ctx), SM3_DIGEST_LENGTH, SM3_BLOCK_SIZE }; const struct DigestInfo *digest_SM3(void) { return &sm3; } 注意:pgbouncer的源码中不支持sm3。sm3相关的都是我自己添加的。 结合源码中md5,讲下我添加的sm3,整体上正确吗?(不考虑其他未涉及到的文件)

这是我的哈希算法的代码:在Rho步骤中有错误,能帮我检查出来吗?#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #define ROL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) int mod(int a, int b) { if (b < 0) return mod(-a, -b); int ret = a % b; return ret < 0 ? ret + b : ret; } uint64_t **sha3_round(uint64_t **A, uint64_t RC, int round) { uint64_t C[5]; uint64_t D[5]; uint64_t B[5][5]; /* Theta step */ C[0] = A[0][0] ^ A[0][1] ^ A[0][2] ^ A[0][3] ^ A[0][4]; C[1] = A[1][0] ^ A[1][1] ^ A[1][2] ^ A[1][3] ^ A[1][4]; C[2] = A[2][0] ^ A[2][1] ^ A[2][2] ^ A[2][3] ^ A[2][4]; C[3] = A[3][0] ^ A[3][1] ^ A[3][2] ^ A[3][3] ^ A[3][4]; C[4] = A[4][0] ^ A[4][1] ^ A[4][2] ^ A[4][3] ^ A[4][4]; // 计算D[0]到D[4] D[0] = C[mod(4,5)] ^ ROL64(C[mod(1,5)], 1); D[1] = C[mod(0,5)] ^ ROL64(C[mod(2,5)], 1); D[2] = C[mod(1,5)] ^ ROL64(C[mod(3,5)], 1); D[3] = C[mod(2,5)] ^ ROL64(C[mod(4,5)], 1); D[4] = C[mod(3,5)] ^ ROL64(C[mod(0,5)], 1); // 应用D到A矩阵(完全展开) A[0][0] ^= D[0]; A[0][1] ^= D[0]; A[0][2] ^= D[0]; A[0][3] ^= D[0]; A[0][4] ^= D[0]; A[1][0] ^= D[1]; A[1][1] ^= D[1]; A[1][2] ^= D[1]; A[1][3] ^= D[1]; A[1][4] ^= D[1]; A[2][0] ^= D[2]; A[2][1] ^= D[2]; A[2][2] ^= D[2]; A[2][3] ^= D[2]; A[2][4] ^= D[2]; A[3][0] ^= D[3]; A[3][1] ^= D[3]; A[3][2] ^= D[3]; A[3][3] ^= D[3]; A[3][4] ^= D[3]; A[4][0] ^= D[4]; A[4][1] ^= D[4]; A[4][2] ^= D[4]; A[4][3] ^= D[4]; A[4][4] ^= D[4]; #ifdef DEBUG printf("[DEBUG] Round %d - After Theta step:\n", round); for (uint8_t ix = 0; ix < 5; ix++) { for (uint8_t iy = 0; iy < 5; iy++) { printf("A[%u][%u] = %016llx ", ix, iy, (unsigned long long) A[ix][iy]); } printf("\n"); } printf("\n"); #endif // 预定义的Rho步骤参数:24个(x,y)坐标及其对应的旋转位数 static const struct { uint8_t x, y; // 源坐标 uint8_t rot; // 旋转位数 uint8_t new_x, new_y; // 下一个坐标 } rho_params[24] = { {1, 0, 1, 0, 2}, // t=0 {0, 2, 3, 2, 1}, // t=1 {2, 1, 6, 1, 3}, // t=2 {1, 2, 10, 3, 2}, // t=3 {2, 3, 15, 3, 4}, // t=4 {3, 3, 21, 0, 3}, // t=5 {3, 0, 28, 0, 1}, // t=6 {0, 1, 36, 1, 4}, // t=7 {1, 3, 45, 4, 2}, // t=8 {3, 1, 55, 2, 4}, // t=9 {1, 4, 2, 4, 0}, // t=10 {4, 4, 14, 0, 4}, // t=11 {4, 0, 27, 4, 3}, // t=12 {0, 3, 41, 3, 0}, // t=13 {3, 4, 56, 3, 1}, // t=14 {4, 3, 8, 1, 0}, // t=15 {3, 2, 25, 0, 0}, // t=16 {2, 4, 43, 0, 2}, // t=17 {4, 2, 62, 2, 0}, // t=18 {2, 0, 18, 2, 3}, // t=19 {0, 4, 39, 3, 3}, // t=20 {4, 1, 61, 3, 2}, // t=21 {1, 1, 20, 2, 2}, // t=22 {4, 0, 44, 2, 1} // t=23 }; /* Rho step */ B[0][0] = A[0][0]; // t=0到23完全展开 B[1][0] = ROL64(A[1][0], 1); // t=0 B[0][2] = ROL64(A[0][2], 3); // t=1 B[2][1] = ROL64(A[2][1], 6); // t=2 B[1][2] = ROL64(A[1][2], 10); // t=3 B[2][3] = ROL64(A[2][3], 15); // t=4 B[3][3] = ROL64(A[3][3], 21); // t=5 B[3][0] = ROL64(A[3][0], 28); // t=6 B[0][1] = ROL64(A[0][1], 36); // t=7 B[1][3] = ROL64(A[1][3], 45); // t=8 B[3][1] = ROL64(A[3][1], 55); // t=9 B[1][4] = ROL64(A[1][4], 2); // t=10 B[4][4] = ROL64(A[4][4], 14); // t=11 B[4][0] = ROL64(A[4][0], 27); // t=12 B[0][3] = ROL64(A[0][3], 41); // t=13 B[3][4] = ROL64(A[3][4], 56); // t=14 B[4][3] = ROL64(A[4][3], 8); // t=15 B[3][2] = ROL64(A[3][2], 25); // t=16 B[2][4] = ROL64(A[2][4], 43); // t=17 B[4][2] = ROL64(A[4][2], 62); // t=18 B[2][0] = ROL64(A[2][0], 18); // t=19 B[0][4] = ROL64(A[0][4], 39); // t=20 B[4][1] = ROL64(A[4][1], 61); // t=21 B[1][1] = ROL64(A[1][1], 20); // t=22 B[3][4] = ROL64(A[3][4], 44); // t=23 (注意:这是正确的最终位置) #ifdef DEBUG printf("[DEBUG] Round %d - After Rho step:\n", round); for (uint8_t ix = 0; ix < 5; ix++) { for (uint8_t iy = 0; iy < 5; iy++) { printf("B[%u][%u] = %016llx ", ix, iy, (unsigned long long) B[ix][iy]); } printf("\n"); } printf("\n"); #endif /* Pi step */ uint64_t T[5][5]; T[0][0] = B[0][0]; // (0,0)->(0,0) T[1][3] = B[0][1]; // (0,1)->(1,3) T[2][1] = B[0][2]; // (0,2)->(2,1) T[3][4] = B[0][3]; // (0,3)->(3,4) T[4][2] = B[0][4]; // (0,4)->(4,2) // 行1 (x=1) T[0][3] = B[1][0]; // (1,0)->(0,3) T[1][1] = B[1][1]; // (1,1)->(1,1) T[2][4] = B[1][2]; // (1,2)->(2,4) T[3][2] = B[1][3]; // (1,3)->(3,2) T[4][0] = B[1][4]; // (1,4)->(4,0) // 行2 (x=2) T[0][1] = B[2][0]; // (2,0)->(0,1) T[1][4] = B[2][1]; // (2,1)->(1,4) T[2][2] = B[2][2]; // (2,2)->(2,2) T[3][0] = B[2][3]; // (2,3)->(3,0) T[4][3] = B[2][4]; // (2,4)->(4,3) // 行3 (x=3) T[0][4] = B[3][0]; // (3,0)->(0,4) T[1][2] = B[3][1]; // (3,1)->(1,2) T[2][0] = B[3][2]; // (3,2)->(2,0) T[3][3] = B[3][3]; // (3,3)->(3,3) T[4][1] = B[3][4]; // (3,4)->(4,1) // 行4 (x=4) T[0][2] = B[4][0]; // (4,0)->(0,2) T[1][0] = B[4][1]; // (4,1)->(1,0) T[2][3] = B[4][2]; // (4,2)->(2,3) T[3][1] = B[4][3]; // (4,3)->(3,1) T[4][4] = B[4][4]; // (4,4)->(4,4) memcpy(B, T, sizeof(T)); #ifdef DEBUG printf("[DEBUG] Round %d - After Pi step:\n", round); for (uint8_t ix = 0; ix < 5; ix++) { for (uint8_t iy = 0; iy < 5; iy++) { printf("B[%u][%u] = %016llx ", ix, iy, (unsigned long long) B[ix][iy]); } printf("\n"); } printf("\n"); #endif /* Xi state */ A[0][0] = B[0][0] ^ (~B[1][0] & B[2][0]); A[0][1] = B[0][1] ^ (~B[1][1] & B[2][1]); A[0][2] = B[0][2] ^ (~B[1][2] & B[2][2]); A[0][3] = B[0][3] ^ (~B[1][3] & B[2][3]); A[0][4] = B[0][4] ^ (~B[1][4] & B[2][4]); // 行1 A[1][0] = B[1][0] ^ (~B[2][0] & B[3][0]); A[1][1] = B[1][1] ^ (~B[2][1] & B[3][1]); A[1][2] = B[1][2] ^ (~B[2][2] & B[3][2]); A[1][3] = B[1][3] ^ (~B[2][3] & B[3][3]); A[1][4] = B[1][4] ^ (~B[2][4] & B[3][4]); // 行2 A[2][0] = B[2][0] ^ (~B[3][0] & B[4][0]); A[2][1] = B[2][1] ^ (~B[3][1] & B[4][1]); A[2][2] = B[2][2] ^ (~B[3][2] & B[4][2]); A[2][3] = B[2][3] ^ (~B[3][3] & B[4][3]); A[2][4] = B[2][4] ^ (~B[3][4] & B[4][4]); // 行3 A[3][0] = B[3][0] ^ (~B[4][0] & B[0][0]); A[3][1] = B[3][1] ^ (~B[4][1] & B[0][1]); A[3][2] = B[3][2] ^ (~B[4][2] & B[0][2]); A[3][3] = B[3][3] ^ (~B[4][3] & B[0][3]); A[3][4] = B[3][4] ^ (~B[4][4] & B[0][4]); // 行4 A[4][0] = B[4][0] ^ (~B[0][0] & B[1][0]); A[4][1] = B[4][1] ^ (~B[0][1] & B[1][1]); A[4][2] = B[4][2] ^ (~B[0][2] & B[1][2]); A[4][3] = B[4][3] ^ (~B[0][3] & B[1][3]); A[4][4] = B[4][4] ^ (~B[0][4] & B[1][4]); #ifdef DEBUG printf("[DEBUG] Round %d - After Xi step:\n", round); for (uint8_t ix = 0; ix < 5; ix++) { for (uint8_t iy = 0; iy < 5; iy++) { printf("A[%u][%u] = %016llx ", ix, iy, (unsigned long long) A[ix][iy]); } printf("\n"); } printf("\n"); #endif /* Last step */ A[0][0] = A[0][0] ^ RC; #ifdef DEBUG printf("[DEBUG] Round %d - After last step (RC):\n", round); for (uint8_t ix = 0; ix < 5; ix++) { for (uint8_t iy = 0; iy < 5; iy++) { printf("A[%u][%u] = %016llx ", ix, iy, (unsigned long long) A[ix][iy]); } printf("\n"); } printf("\n"); #endif return A; }#include "round.h" uint64_t **keccak_f(uint64_t **A) { uint64_t RC[24]; uint8_t LFSR = 0x01; // Generate 24 round constants for (int i = 0; i < 24; i++) { RC[i] = 0; for (int j = 0; j < 7; j++) { uint8_t bit = LFSR & 1; if (bit) { RC[i] |= (uint64_t)1 << ((1 << j) - 1); } uint8_t temp = LFSR; LFSR <<= 1; if (temp & 0x80) { LFSR ^= 0x71; } } A = sha3_round(A, RC[i], i); } return A; }

最新推荐

recommend-type

已解决:No &#39;Access-Control-Allow-Origin&#39;跨域问题

跨域问题在Web开发中是一个常见的挑战,尤其是在前后端分离的项目中。"No 'Access-Control-Allow-Origin'"错误是由于浏览器的同源策略(Same-origin Policy)限制所致,该策略规定,JavaScript发起的Ajax请求只能...
recommend-type

freude弗莱德FP-12A电脑DSP调音软件下载

freude弗莱德FP-12A电脑DSP调音软件下载
recommend-type

VC图像编程全面资料及程序汇总

【标题】:"精通VC图像编程资料全览" 【知识点】: VC即Visual C++,是微软公司推出的一个集成开发环境(IDE),专门用于C++语言的开发。VC图像编程涉及到如何在VC++开发环境中处理和操作图像。在VC图像编程中,开发者通常会使用到Windows API中的GDI(图形设备接口)或GDI+来进行图形绘制,以及DirectX中的Direct2D或DirectDraw进行更高级的图形处理。 1. GDI(图形设备接口): - GDI是Windows操作系统提供的一套应用程序接口,它允许应用程序通过设备无关的方式绘制图形。 - 在VC图像编程中,主要使用CDC类(设备上下文类)来调用GDI函数进行绘制,比如绘制线条、填充颜色、显示文本等。 - CDC类提供了很多函数,比如`MoveTo`、`LineTo`、`Rectangle`、`Ellipse`、`Polygon`等,用于绘制基本的图形。 - 对于图像处理,可以使用`StretchBlt`、`BitBlt`、`TransparentBlt`等函数进行图像的位块传输。 2. GDI+: - GDI+是GDI的后继技术,提供了更丰富的图形处理功能。 - GDI+通过使用`Graphics`类来提供图像的绘制、文本的渲染、图像的处理和颜色管理等功能。 - GDI+引入了对矢量图形、渐变色、复杂的文本格式和坐标空间等更高级的图形处理功能。 - `Image`类是GDI+中用于图像操作的基础类,通过它可以进行图像的加载、保存、旋转、缩放等操作。 3. DirectX: - DirectX是微软推出的一系列API集合,用于在Windows平台上进行高性能多媒体编程。 - DirectX中的Direct2D是用于硬件加速的二维图形API,专门用于UI元素和简单的图形渲染。 - DirectDraw主要用于硬件加速的位图操作,比如全屏游戏开发中的画面渲染。 4. 位图操作: - 在VC图像编程中,位图操作是一个重要的部分。需要了解如何加载、保存和处理位图(BMP)文件。 - 可以使用位图文件格式的解析,来访问位图的像素数据,进行像素级别的图像处理和修改。 5. 高级图像处理技术: - 包括图像滤镜、图像转换、图像压缩和解压缩技术。 - 需要掌握一些图像处理算法,比如卷积、FFT(快速傅里叶变换)、DCT(离散余弦变换)等。 - 了解图像的色彩空间转换,比如RGB到YUV的转换,这在视频处理中非常重要。 6. 图像库的使用: - 除了直接使用API进行图像处理之外,还可以使用开源的图像处理库,如OpenCV。 - OpenCV是一个跨平台的计算机视觉和机器学习软件库,它提供了很多高级的图像处理功能。 【压缩包子文件的文件名称列表】: VC++ 文件名称列表显示为"VC++",这表明文件包中可能包含了Visual C++的项目、源代码文件、动态链接库(DLLs)、编译器设置、链接器设置等。如果要使用这些文件进行VC图像编程,需要确保Visual C++开发环境已经安装并且配置好,同时需要安装好所有依赖的库和工具。 要开始VC图像编程,开发者需要具备C++编程基础,熟悉Windows编程概念,并且对图形学有一定的了解。掌握VC图像编程技巧,对于进行桌面应用程序开发、图像处理软件开发以及游戏开发等都是至关重要的。
recommend-type

Pokemmo响应速度翻倍:多线程处理的高级技巧

# 摘要 多线程处理是提高软件并发性能和响应速度的关键技术,本文从基础概念与优势出发,深入探讨了多线程的实现机制,包括线程模型、调度算法、编程关键技术、线程安全性最佳实践、死锁预防与处理等方面。通
recommend-type

人名列表滚动抽奖

<think>嗯,用户想实现一个滚动抽奖功能,需要前端动画效果和随机选择逻辑。首先,我得考虑前端怎么实现滚动效果。可能用CSS动画或者JavaScript的requestAnimationFrame?比如,使用CSS的@keyframes来控制位移,或者用JS动态更新样式。然后,随机选择算法,可能需要确保公平性,比如用Fisher-Yates洗牌算法,或者用Math.random()来生成随机索引。然后,用户可能需要平滑的滚动动画,比如先快速滚动,然后逐渐减速,最后停在选中的人名上。这可能需要设置定时器,逐步改变位置,或者使用CSS过渡效果。另外,还要考虑性能,避免页面卡顿,可能需要使用硬件加
recommend-type

一站式JSF开发环境:即解压即用JAR包

标题:“jsf开发完整JAR包”所指的知识点: 1. JSF全称JavaServer Faces,是Java EE(现EE4J)规范之一,用于简化Java Web应用中基于组件的用户界面构建。JSF提供了一种模型-视图-控制器(MVC)架构的实现,使得开发者可以将业务逻辑与页面表示分离。 2. “开发完整包”意味着这个JAR包包含了JSF开发所需的所有类库和资源文件。通常来说,一个完整的JSF包会包含核心的JSF库,以及一些可选的扩展库,例如PrimeFaces、RichFaces等,这些扩展库提供了额外的用户界面组件。 3. 在一个项目中使用JSF,开发者无需单独添加每个必要的JAR文件到项目的构建路径中。因为打包成一个完整的JAR包后,所有这些依赖都被整合在一起,极大地方便了开发者的部署工作。 4. “解压之后就可以直接导入工程中使用”表明这个JAR包是一个可执行的归档文件,可能是一个EAR包或者一个可直接部署的Java应用包。解压后,开发者只需将其内容导入到他们的IDE(如Eclipse或IntelliJ IDEA)中,或者将其放置在Web应用服务器的正确目录下,就可以立即进行开发。 描述中所指的知识点: 1. “解压之后就可以直接导入工程中使用”说明这个JAR包是预先配置好的,它可能包含了所有必要的配置文件,例如web.xml、faces-config.xml等,这些文件是JSF项目运行所必需的。 2. 直接使用意味着减少了开发者配置环境和处理依赖的时间,有助于提高开发效率。 标签“jsf jar包”所指的知识点: 1. 标签指明了JAR包的内容是专门针对JSF框架的。因此,这个JAR包包含了JSF规范所定义的API以及可能包含的具体实现,比如Mojarra或MyFaces。 2. “jar包”是一种Java平台的归档文件格式,用于聚合多个文件到一个文件中。在JSF开发中,JAR文件经常被用来打包和分发库或应用程序。 文件名称列表“jsf”所指的知识点: 1. “jsf”文件名可能意味着这是JSF开发的核心库,它应该包含了所有核心的JavaServer Faces类文件以及资源文件。 2. 如果是使用特定版本的JSF,例如“jsf-2.2.jar”,则表明文件内包含了对应版本的JSF实现。这种情况下,开发者必须确认他们所使用的Web服务器或应用程序服务器支持该版本的JSF。 3. 文件名称也可能是“jsf-components.jar”、“jsf-impl.jar”等,表明这个JAR包是JSF的一个子模块或特定功能组件。例如,“jsf-components.jar”可能包含了一系列用于在JSF应用中使用的自定义组件。 4. 对于开发者而言,了解文件名称中所蕴含的信息非常重要,因为这将决定他们需要下载哪些JAR包来满足特定项目的需求。 综合以上信息,开发者在使用JSF进行Java Web应用开发时,会通过一个预先配置好的JAR包来快速地搭建和启动项目。这样做不仅简化了项目初始化的过程,也使得开发者能够更加聚焦于业务逻辑的实现和界面设计,而不必深究底层框架配置的细节。
recommend-type

Pokemmo内存优化揭秘:专家教你如何降低50%资源消耗

# 摘要 本文综述了Pokemmo游戏的内存优化方法,从内存管理基础出发,探讨内存使用效率的影响因素,并介绍了性能监控与分析工具。在内存优化实践技巧章节中,详细讨论了代码层面的优化、数据结构和算法选择对内存效率的影响,并通过案例分析展示了实际的优化过程。针对Pokemmo游戏特点,分析了内存消耗特性并提出了特定优化技术。最后,本文展望了未来内存管理技术的发展方向,以及游戏开发中面临的新挑战,为Pokemmo及类似游戏提供了优化建议。 # 关键字 内存优化;内存管理;性能监控;数据结构;算法效率;游戏开发 参考资源链接:[Pokemmo必备资源包:四种ROM与汉化补丁](https://we
recommend-type

直接访问子路由是吧

<think>我们正在使用Vue2,因此需要参考VueRouterv3的文档(因为Vue2对应VueRouterv3,Vue3对应VueRouterv4)。用户的问题是:如何配置路由以支持直接访问子路由?即,在Vue2中,我们希望直接通过URL访问嵌套的子路由(例如:/parent/child),而不仅仅是先访问父路由再导航到子路由。根据之前的回答和引用,我们已经知道:1.在父路由的配置中,使用`children`数组来定义子路由。2.子路由的`path`不能以斜杠开头(例如:'child'而不是'/child'),这样它就会基于父路由的路径进行拼接。3.在父组件的模板中放置`<router-
recommend-type

C++函数库查询辞典使用指南与功能介绍

标题中提到的“C++函数库查询辞典”指的是一个参考工具书或者是一个软件应用,专门用来查询C++编程语言中提供的标准库中的函数。C++是一种静态类型、编译式、通用编程语言,它支持多种编程范式,包括过程化、面向对象和泛型编程。C++标准库是一组包含函数、类、迭代器和模板的库,它为C++程序员提供标准算法和数据结构。 描述中提供的内容并没有给出实际的知识点,只是重复了标题的内容,并且有一串无关的字符“sdfsdfsdffffffffffffffffff”,因此这部分内容无法提供有价值的信息。 标签“C++ 函数库 查询辞典”强调了该工具的用途,即帮助开发者查询C++的标准库函数。它可能包含每个函数的详细说明、语法、使用方法、参数说明以及示例代码等,是学习和开发过程中不可或缺的参考资源。 文件名称“c++函数库查询辞典.exe”表明这是一个可执行程序。在Windows操作系统中,以“.exe”结尾的文件通常是可执行程序。这意味着用户可以通过双击或者命令行工具来运行这个程序,进而使用其中的查询功能查找C++标准库中各类函数的详细信息。 详细知识点如下: 1. C++标准库的组成: C++标准库由多个组件构成,包括输入输出流(iostream)、算法(algorithm)、容器(container)、迭代器(iterator)、字符串处理(string)、数值计算(numeric)、本地化(locale)等。 2. 输入输出流(iostream)库: 提供输入输出操作的基本功能。使用诸如iostream、fstream、sstream等头文件中的类和对象(如cin, cout, cerr等)来实现基本的输入输出操作。 3. 算法(algorithm)库: 包含对容器进行操作的大量模板函数,如排序(sort)、查找(find)、拷贝(copy)等。 4. 容器(container)库: 提供各种数据结构,如向量(vector)、列表(list)、队列(queue)、映射(map)等。 5. 迭代器(iterator): 迭代器提供了一种方法来访问容器中的元素,同时隐藏了容器的内部结构。 6. 字符串处理(string)库: C++标准库中的字符串类提供了丰富的功能用于处理字符串。 7. 数值计算(numeric)库: 提供数值计算所需的函数和类,比如对复数的支持和数值算法。 8. 本地化(locale)库: 提供本地化相关的功能,比如日期、时间的格式化显示以及字符的本地化比较。 9. 错误处理和异常: C++通过throw、try、catch关键字和标准异常类提供了一套异常处理机制。 10. 智能指针: C++11及其后续版本提供了智能指针(如unique_ptr、shared_ptr、weak_ptr)来自动管理动态分配的内存。 11. lambda表达式: 在C++11中引入,允许临时创建匿名函数对象。 12. C++11新特性: 包括范围for循环、移动语义、类内初始化器、auto类型推导等。 使用C++函数库查询辞典的用户可能需要对C++的基础知识有一定的掌握,例如变量、数据类型、控制结构、函数以及面向对象的概念等。了解C++标准库的结构和内容能够帮助程序员有效地利用库函数进行软件开发,提高编程效率并减少重复造轮子的工作。 总结来说,一个C++函数库查询辞典工具对于C++程序员来说是一个非常有用的资源,它能够提供快速查找标准库函数的能力,帮助程序员更高效地解决问题和进行学习。同时,随着C++标准的不断更新,例如C++11、C++14、C++17和C++20,函数库查询辞典也会不断地更新以包含新的特性,这对于紧跟技术发展的开发者来说尤为重要。
recommend-type

【bat脚本安全最佳实践】:保护你的系统与脚本安全的黄金法则

# 摘要 本文旨在全面阐述BAT脚本的基础知识、安全编写原则、审查与优化方法以及在企业环境中的安全应用。通过深入分析脚本安全基础、常见安全陷阱及脚本的权限管理,文章提出了安全编写的具体实践和预防措施。本文详细介绍了脚本安全审查流程、代码优化、错误处理和安全更新维护策略。在企业应用方面,探讨了企业安全政策制定、脚本审计和版本控制以及外部威胁的防范措施。通过案例分析,总结了脚本