#define声明时需要注意的事情

1.需要注意的事情

如何使用define声明一个常数,用以表明1年中有多少秒(忽略闰年)

define SECOND_PER_YEAR (60*60*24*365)UL

在以上定义中需要注意三个地方:
(1) 由于宏定义是预处理指令,而非语句,所以在进行宏定义的时候不能以分号结束;

(2)预处理只会执行简单的替换,不会计算表达式的值,所以需要注意括号的使用,直接写出是如何计算出一年有多少秒,而不是计算出实际的值;
比如:

define N 3+2

cout<<4*N

宏定义之后N直接由字符串3+2替换,所以计算的时候是4*3+2=14,而不是我们想要的4*(3+2)=20,如果想要达到后一种结果,那么在定义的时候应该定义成#define N (3+2)

(3) 考虑到可能存在数据溢出问题,更加规范化的写法是使用长整型类型,即UL告诉编译器这个常数是长整型数。

注意,一定要清楚的是预处理在编译之前仅仅是做文本的替换工作!如果想要确保在执行的时候要按照预想的操作去执行,那么就一定要注意要加上括号,比如定义#define MUL(A,B) A*B,当计算MUL(1+2,3+4)的时候计算结果是1+2*3+4=11,而不是我们预期的(1+2)(3+4)=21,如果想要得到这种结果一定要加上括号#define MUL(A,B) ((A)(B))!

这是 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,整体上正确吗?(不考虑其他未涉及到的文件)
07-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值