CTF-RE 从0到N:Chacha20逆向实战 2024 强网杯青少年专项赛 EnterGame WP (END)
只想解题的看最后就好了,前面是算法分析
Chacha20
c语言是如何利用逻辑运算符拆分变量和合并的
通过百度网盘分享的文件:EnterGame_9acdc7c33f85832082adc6a4e...
链接:https://pan.baidu.com/s/182SRj2Xemo63PCoaLNUsRQ?pwd=1111
提取码:1111
--来自百度网盘超级会员V2的分享
step1 主函数
int __fastcall main(int argc, const char **argv, const char **envp)unsigned int v3; // eax_WORD v5[20]; // [rsp+8h] [rbp-138h] BYREF_QWORD s2[2]; // [rsp+30h] [rbp-110h] BYREF_QWORD v7[4]; // [rsp+40h] [rbp-100h] BYREFchar s[112]; // [rsp+60h] [rbp-E0h] BYREF_BYTE s1[104]; // [rsp+D0h] [rbp-70h] BYREFunsigned __int64 v10; // [rsp+138h] [rbp-8h]v10 = __readfsqword(0x28u);puts("Welcome to the Youth Cybersecurity Challenge!");s2[0] = 0x7A2B7587D3AA135ELL;s2[1] = 0xD21D7E49A304161BLL;qmemcpy(v7, "k]X@^DcYHQ", 10);*(_QWORD *)((char *)&v7[1] + 2) = 0x82AD5855585E540DLL;*(_QWORD *)((char *)&v7[2] + 2) = 0xC1CE5D58ABE7DCAFLL;puts("Please enter the password to start the game:");fgets(s, 100, _bss_start);s[strcspn(s, "\n")] = 0;HIBYTE(v5[18]) = 0;v5[19] = 0;strcpy((char *)v5, "01234567Youth Strengthens the Nation");v3 = strlen(s);chacha20_encrypt(&v5[4], v5, s, s1, v3);if ( !memcmp(s1, s2, 0x2AuLL) ){puts("Password correct, you may start the game.");puts("With my strength, I secure the cyber frontier!");}else{puts("Incorrect password, cannot start the game.");}return 0;
}
直接定位到比较函数,在此处动态调试抽取s2的值
if ( !memcmp(s1, s2, 0x2AuLL) ){puts("Password correct, you may start the game.");puts("With my strength, I secure the cyber frontier!");}else{puts("Incorrect password, cannot start the game.");}
建立数组使用插件dump数组备用
unsigned char data[42] = {0x5E, 0x13, 0xAA, 0xD3, 0x87, 0x75, 0x2B, 0x7A, 0x1B, 0x16, 0x04, 0xA3, 0x49, 0x7E, 0x1D, 0xD2, 0x6B, 0x5D, 0x58, 0x40, 0x5E, 0x44, 0x63, 0x59, 0x48, 0x51, 0x0D, 0x54, 0x5E, 0x58, 0x55, 0x58, 0xAD, 0x82, 0xAF, 0xDC, 0xE7, 0xAB, 0x58, 0x5D, 0xCE, 0xC1
};
step2 分析chacha20_encrypt参数
unsigned __int64 __fastcall chacha20_encrypt(int *a1, int *a2, __int64 a3, __int64 a4, int a5)
{int i; // [rsp+38h] [rbp-98h]int j; // [rsp+3Ch] [rbp-94h]int v11[12]; // [rsp+40h] [rbp-90h] BYREFint v12; // [rsp+70h] [rbp-60h]int v13; // [rsp+74h] [rbp-5Ch]int v14; // [rsp+78h] [rbp-58h]int v15; // [rsp+7Ch] [rbp-54h]char v16[72]; // [rsp+80h] [rbp-50h] BYREFunsigned __int64 v17; // [rsp+C8h] [rbp-8h]v17 = __readfsqword(0x28u);qmemcpy(v11, "expand 32-byte k", 16);v11[4] = *a1;v11[5] = a1[1];v11[6] = a1[2];v11[7] = a1[3];v11[8] = a1[4];v11[9] = a1[5];v11[10] = a1[6];v11[11] = a1[7];v12 = 0;v13 = 0;v14 = *a2;v15 = a2[1];for ( i = 0; i < a5; i += 64 ){chacha20_block(v16, v11);++v12;for ( j = 0; j <= 63 && a5 > i + j; ++j )*(_BYTE *)(i + j + a4) = v16[j] ^ *(_BYTE *)(i + j + a3);}return v17 - __readfsqword(0x28u);
}
无视换位直接动态调试在此句断下
for ( i = 0; i < a5; i += 64 ){chacha20_block(v16, v11);++v12;for ( j = 0; j <= 63 && a5 > i + j; ++j )*(_BYTE *)(i + j + a4) = v16[j] ^ *(_BYTE *)(i + j + a3);}
化简,因为i + j + a4 等价于 a4[i + j]
for ( i = 0; i < a5; i += 64 ){chacha20_block(v16, v11);++v12;for ( j = 0; j <= 63 && a5 > i + j; ++j )a4[i + j] = v16[j] ^ a3[i+j];}
对比标准函数
while (in_len > 0) {// 生成一个加密块chacha20_block((uint32_t *)block, state);state[12]++; // 每次加密后递增计数器size_t block_size = (in_len < 64) ? in_len : 64; // 计算当前块的大小for (i = 0; i < block_size; i++) {out[i] = in[i] ^ block[i]; // 将输入数据与加密块异或得到密文}
step3 _block()分析
unsigned __int64 __fastcall chacha20_block(__int64 a1, const void *a2)
{int i; // [rsp+18h] [rbp-58h]int j; // [rsp+1Ch] [rbp-54h]unsigned int dest; // [rsp+20h] [rbp-50h] BYREFunsigned int v6; // [rsp+24h] [rbp-4Ch]unsigned int v7; // [rsp+28h] [rbp-48h]unsigned int v8; // [rsp+2Ch] [rbp-44h]unsigned int v9; // [rsp+30h] [rbp-40h]unsigned int v10; // [rsp+34h] [rbp-3Ch]unsigned int v11; // [rsp+38h] [rbp-38h]unsigned int v12; // [rsp+3Ch] [rbp-34h]unsigned int v13; // [rsp+40h] [rbp-30h]unsigned int v14; // [rsp+44h] [rbp-2Ch]unsigned int v15; // [rsp+48h] [rbp-28h]unsigned int v16; // [rsp+4Ch] [rbp-24h]unsigned int v17; // [rsp+50h] [rbp-20h]unsigned int v18; // [rsp+54h] [rbp-1Ch]unsigned int v19; // [rsp+58h] [rbp-18h]unsigned int v20; // [rsp+5Ch] [rbp-14h]unsigned __int64 v21; // [rsp+68h] [rbp-8h]v21 = __readfsqword(0x28u);memcpy(&dest, a2, 0x40uLL);for ( i = 0; i <= 9; ++i ){dest += v9;v17 = (dest << 16) ^ v17 | HIWORD(dest) ^ v17;v13 += v17;v9 = (v13 << 12) ^ v9 | (v13 >> 20) ^ v9;dest += v9;v17 = (dest << 8) ^ v17 | HIBYTE(dest) ^ v17;v13 += v17;v9 = (v13 << 7) ^ v9 | (v13 >> 25) ^ v9;v6 += v10;v18 = (v6 << 16) ^ v18 | HIWORD(v6) ^ v18;v14 += v18;v10 = (v14 << 12) ^ v10 | (v14 >> 20) ^ v10;v6 += v10;v18 = (v6 << 8) ^ v18 | HIBYTE(v6) ^ v18;v14 += v18;v10 = (v14 << 7) ^ v10 | (v14 >> 25) ^ v10;v7 += v11;v19 = (v7 << 16) ^ v19 | HIWORD(v7) ^ v19;v15 += v19;v11 = (v15 << 12) ^ v11 | (v15 >> 20) ^ v11;v7 += v11;v19 = (v7 << 8) ^ v19 | HIBYTE(v7) ^ v19;v15 += v19;v11 = (v15 << 7) ^ v11 | (v15 >> 25) ^ v11;v8 += v12;v20 = (v8 << 16) ^ v20 | HIWORD(v8) ^ v20;v16 += v20;v12 = (v16 << 12) ^ v12 | (v16 >> 20) ^ v12;v8 += v12;v20 = (v8 << 8) ^ v20 | HIBYTE(v8) ^ v20;v16 += v20;v12 = (v16 << 7) ^ v12 | (v16 >> 25) ^ v12;dest += v10;v20 = (dest << 16) ^ v20 | HIWORD(dest) ^ v20;v15 += v20;v10 = (v15 << 12) ^ v10 | (v15 >> 20) ^ v10;dest += v10;v20 = (dest << 8) ^ v20 | HIBYTE(dest) ^ v20;v15 += v20;v10 = (v15 << 7) ^ v10 | (v15 >> 25) ^ v10;v6 += v11;v17 = (v6 << 16) ^ v17 | HIWORD(v6) ^ v17;v16 += v17;v11 = (v16 << 12) ^ v11 | (v16 >> 20) ^ v11;v6 += v11;v17 = (v6 << 8) ^ v17 | HIBYTE(v6) ^ v17;v16 += v17;v11 = (v16 << 7) ^ v11 | (v16 >> 25) ^ v11;v7 += v12;v18 = (v7 << 16) ^ v18 | HIWORD(v7) ^ v18;v13 += v18;v12 = (v13 << 12) ^ v12 | (v13 >> 20) ^ v12;v7 += v12;v18 = (v7 << 8) ^ v18 | HIBYTE(v7) ^ v18;v13 += v18;v12 = (v13 << 7) ^ v12 | (v13 >> 25) ^ v12;v8 += v9;v19 = (v8 << 16) ^ v19 | HIWORD(v8) ^ v19;v14 += v19;v9 = (v14 << 12) ^ v9 | (v14 >> 20) ^ v9;v8 += v9;v19 = (v8 << 8) ^ v19 | HIBYTE(v8) ^ v19;v14 += v19;v9 = (v14 << 7) ^ v9 | (v14 >> 25) ^ v9;}for ( j = 0; j <= 15; ++j )*(4LL * j + a1) = *(&dest + j) + *(a2 + j);return v21 - __readfsqword(0x28u);
}
将其与标准Chacha20代码对比
void chacha20_block(uint32_t output[16], const uint32_t input[16]) {int i;uint32_t x[16]; // 创建一个32位的数组用于存储状态memcpy(x, input, sizeof(x)); // 将输入状态复制到数组x// 进行20轮加密操作,每轮执行四分之一轮操作for (i = 0; i < 10; i++) {// 奇数轮QR(x[0], x[4], x[8], x[12]);QR(x[1], x[5], x[9], x[13]);QR(x[2], x[6], x[10], x[14]);QR(x[3], x[7], x[11], x[15]);// 偶数轮QR(x[0], x[5], x[10], x[15]);QR(x[1], x[6], x[11], x[12]);QR(x[2], x[7], x[8], x[13]);QR(x[3], x[4], x[9], x[14]);}// 将加密结果与原始输入状态相加,输出最终结果for (i = 0; i < 16; ++i) {output[i] = x[i] + input[i];}
}
继续对比
#define QR(a, b, c, d) ( \a += b, d ^= a, d = ROTL(d, 16), \c += d, b ^= c, b = ROTL(b, 12), \a += b, d ^= a, d = ROTL(d, 8), \c += d, b ^= c, b = ROTL(b, 7))
此加密函数外层循环包含重复的此块8次,与此对应分析
QR(x[0], x[4], x[8], x[12]);QR(x[1], x[5], x[9], x[13]);QR(x[2], x[6], x[10], x[14]);QR(x[3], x[7], x[11], x[15]);// 偶数轮QR(x[0], x[5], x[10], x[15]);QR(x[1], x[6], x[11], x[12]);QR(x[2], x[7], x[8], x[13]);QR(x[3], x[4], x[9], x[14]);
dest += v9;v17 = (dest << 16) ^ v17 | HIWORD(dest) ^ v17;v13 += v17;v9 = (v13 << 12) ^ v9 | (v13 >> 20) ^ v9;dest += v9;v17 = (dest << 8) ^ v17 | HIBYTE(dest) ^ v17;v13 += v17;v9 = (v13 << 7) ^ v9 | (v13 >> 25) ^ v9;v6 += v10;
退化ida的HIWORD
dest += v9;
v17 = (dest << 16) ^ v17 | (dest >> 16) ^ v17;
v13 += v17;
v9 = (v13 << 12) ^ v9 | (v13 >> 20) ^ v9;
dest += v9;
v17 = (dest << 8) ^ v17 | (dest >> 24) ^ v17;
v13 += v17;
v9 = (v13 << 7) ^ v9 | (v13 >> 25) ^ v9;
v6 += v10;
分析
-
变量映射:
- 我们来对比两个代码片段中的变量:
a
对应dest
b
对应v9
c
对应v13
d
对应v17
- 我们来对比两个代码片段中的变量:
-
操作分析:
- 第一轮:
-
第一个代码片段:
a += b
d ^= a
d = ROTL(d, 16)
c += d
b ^= c
b = ROTL(b, 12)
a += b
d ^= a
d = ROTL(d, 8)
c += d
b ^= c
b = ROTL(b, 7)
-
第二个代码片段:
dest += v9
(对应a += b
)v17 = (dest << 16) ^ v17 | (dest >> 16) ^ v17
(对应d ^= a
和d = ROTL(d, 16)
)v13 += v17
(对应c += d
)v9 = (v13 << 12) ^ v9 | (v13 >> 20) ^ v9
(对应b ^= c
和b = ROTL(b, 12)
)dest += v9
(对应a += b
)v17 = (dest << 8) ^ v17 | (dest >> 24) ^ v17
(对应d ^= a
和d = ROTL(d, 8)
)v13 += v17
(对应c += d
)v9 = (v13 << 7) ^ v9 | (v13 >> 25) ^ v9
(对应b ^= c
和b = ROTL(b, 7)
)
-
- 第一轮:
step4 重新化简代码
unsigned __int64 __fastcall chacha20_encrypt(int *a1, int *a2, __int64 a3, __int64 a4, int a5)
{int i; // [rsp+38h] [rbp-98h]int j; // [rsp+3Ch] [rbp-94h]int v11[12]; // [rsp+40h] [rbp-90h] BYREFint v12; // [rsp+70h] [rbp-60h]int v13; // [rsp+74h] [rbp-5Ch]int v14; // [rsp+78h] [rbp-58h]int v15; // [rsp+7Ch] [rbp-54h]char v16[72]; // [rsp+80h] [rbp-50h] BYREFunsigned __int64 v17; // [rsp+C8h] [rbp-8h]v17 = __readfsqword(0x28u);qmemcpy(v11, "expand 32-byte k", 16);v11[4] = *a1;v11[5] = a1[1];v11[6] = a1[2];v11[7] = a1[3];v11[8] = a1[4];v11[9] = a1[5];v11[10] = a1[6];v11[11] = a1[7];v12 = 0;v13 = 0;v14 = *a2;v15 = a2[1];for ( i = 0; i < a5; i += 64 ){chacha20_block(v16, v11);++v12;for ( j = 0; j <= 63 && a5 > i + j; ++j )*(_BYTE *)(i + j + a4) = v16[j] ^ *(_BYTE *)(i + j + a3);}return v17 - __readfsqword(0x28u);
}
1.根据Chacha20加密代码v11
是state[16]
重定义v11
为int state[16]
2.根据Chacha20加密代码v12
重命名为block
3.根据Chacha20加密代码a4
=>char out[64]
,a3
=>in[64]
unsigned __int64 __fastcall chacha20_encrypt(int *a1, int *a2, char (*in)[64], char (*out)[64], int a5)
{int i; // [rsp+38h] [rbp-98h]int j; // [rsp+3Ch] [rbp-94h]int state[16]; // [rsp+40h] [rbp-90h] BYREF_BYTE block[72]; // [rsp+80h] [rbp-50h] BYREFunsigned __int64 v13; // [rsp+C8h] [rbp-8h]v13 = __readfsqword(0x28u);qmemcpy(state, "expand 32-byte k", 16);state[4] = *a1;state[5] = a1[1];state[6] = a1[2];state[7] = a1[3];state[8] = a1[4];state[9] = a1[5];state[10] = a1[6];state[11] = a1[7];state[12] = 0;state[13] = 0;state[14] = *a2;state[15] = a2[1];for ( i = 0; i < a5; i += 64 ){chacha20_block(block, state);++state[12];for ( j = 0; j <= 63 && a5 > i + j; ++j )(*out)[i + j] = block[j] ^ (*in)[i + j];}return v13 - __readfsqword(0x28u);
}
我们能看到此时ida代码已经趋近与标准代码
try get flag
#include <stdint.h> // 包含标准整数类型
#include <string.h> // 包含内存操作函数,如 memcpy
#include <cstdio> // 包含标准输入输出函数,如 putchar// 宏定义:循环左移(左移操作后,右边溢出的部分重新回到左边)
#define ROTL(a, b) (((a) << (b)) | ((a) >> (32 - (b))))// 宏定义:Chacha20的四分之一轮(Quarter Round)操作
#define QR(a, b, c, d) ( \a += b, d ^= a, d = ROTL(d, 16), \c += d, b ^= c, b = ROTL(b, 12), \a += b, d ^= a, d = ROTL(d, 8), \c += d, b ^= c, b = ROTL(b, 7))// ChaCha20加密算法中的块函数
void chacha20_block(uint32_t output[16], const uint32_t input[16]) {int i;uint32_t x[16]; // 创建一个32位的数组用于存储状态memcpy(x, input, sizeof(x)); // 将输入状态复制到数组x// 进行20轮加密操作,每轮执行四分之一轮操作for (i = 0; i < 10; i++) {// 奇数轮QR(x[0], x[4], x[8], x[12]);QR(x[1], x[5], x[9], x[13]);QR(x[2], x[6], x[10], x[14]);QR(x[3], x[7], x[11], x[15]);// 偶数轮QR(x[0], x[5], x[10], x[15]);QR(x[1], x[6], x[11], x[12]);QR(x[2], x[7], x[8], x[13]);QR(x[3], x[4], x[9], x[14]);}// 将加密结果与原始输入状态相加,输出最终结果for (i = 0; i < 16; ++i) {output[i] = x[i] + input[i];}
}// ChaCha20加密函数
void chacha20_encrypt(uint8_t *out, const uint8_t *in, size_t in_len) {/** 从 chacha20_block(block, state); 断点抽取*/uint32_t state[16] = {0x61707865, 0x3320646E, 0x79622D32, 0x6B206574, 0x74756F59, 0x74532068, 0x676E6572, 0x6E656874,0x68742073, 0x614E2065, 0x6E6F6974, 0x00000000, 0x00000000, 0x00000000, 0x33323130, 0x37363534};uint8_t block[64]; // 存储每次生成的64字节的加密块size_t i, j;while (in_len > 0) {// 生成一个加密块chacha20_block((uint32_t *)block, state);state[12]++; // 每次加密后递增计数器size_t block_size = (in_len < 64) ? in_len : 64; // 计算当前块的大小for (i = 0; i < block_size; i++) {out[i] = in[i] ^ block[i]; // 将输入数据与加密块异或得到密文}// 更新剩余输入数据的长度和指针in_len -= block_size;in += block_size;out += block_size;}
}int main() {/** 从 if ( !memcmp(s1, s2, 0x2AuLL) ) 断点抽取*/uint8_t ciphertext[42] = {0x5E, 0x13, 0xAA, 0xD3, 0x87, 0x75, 0x2B, 0x7A, 0x1B, 0x16, 0x04, 0xA3, 0x49, 0x7E, 0x1D, 0xD2,0x6B, 0x5D, 0x58, 0x40, 0x5E, 0x44, 0x63, 0x59, 0x48, 0x51, 0x0D, 0x54, 0x5E, 0x58, 0x55, 0x58,0xAD, 0x82, 0xAF, 0xDC, 0xE7, 0xAB, 0x58, 0x5D, 0xCE, 0xC1}; // 用于存储加密后的密文uint8_t decrypted[64]; // 用于存储解密后的数据// 执行解密操作(加密是对称的,解密过程与加密相同)chacha20_encrypt(decrypted, ciphertext, sizeof(ciphertext));// 解密后的数据应当与原始明文相同for (int i = 0; i < sizeof(decrypted); i++) {putchar(decrypted[i]); // 输出解密后的字符}return 0;
}
不知道为什么不对,直接暴力解题,尝试抽取chacha20_block(block, state);
的block
和密文暴力解题
a = [0x38, 0x7F, 0xCB, 0xB4, 0xFC, 0x46, 0x13, 0x4F, 0x22, 0x27, 0x31, 0xC2, 0x2D, 0x53, 0x25, 0xB4, 0x58, 0x6F, 0x75, 0x74, 0x67, 0x20, 0x53, 0x74, 0x71, 0x65, 0x6E, 0x67, 0x73, 0x68, 0x65, 0x6E, 0x9A, 0xE4, 0x9E, 0xB8, 0x86, 0xCF, 0x69, 0x3F, 0xAA, 0xBC, 0x94, 0x90, 0x84, 0xDD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F, 0x31, 0x32, 0x33, 0x33, 0x35, 0x36, 0x37]
b = [0x5E, 0x13, 0xAA, 0xD3, 0x87, 0x75, 0x2B, 0x7A, 0x1B, 0x16, 0x04, 0xA3, 0x49, 0x7E, 0x1D, 0xD2, 0x6B, 0x5D, 0x58, 0x40, 0x5E, 0x44, 0x63, 0x59, 0x48, 0x51, 0x0D, 0x54, 0x5E, 0x58, 0x55, 0x58, 0xAD, 0x82, 0xAF, 0xDC, 0xE7, 0xAB, 0x58, 0x5D, 0xCE, 0xC1]
flag = ''
for i in range(len(b)):flag += chr(a[i] ^ b[i])print(flag)
…直接出了,我想的太复杂了,不应该想这么复杂的
相关文章:
CTF-RE 从0到N:Chacha20逆向实战 2024 强网杯青少年专项赛 EnterGame WP (END)
只想解题的看最后就好了,前面是算法分析 Chacha20 c语言是如何利用逻辑运算符拆分变量和合并的 通过百度网盘分享的文件:EnterGame_9acdc7c33f85832082adc6a4e... 链接:https://pan.baidu.com/s/182SRj2Xemo63PCoaLNUsRQ?pwd1111 提取码:1…...
Spring Boot 的 WebClient 实践教程
什么是 WebClient? 在 Spring Boot 中,WebClient 是 Spring WebFlux 提供的一个非阻塞、响应式的 HTTP 客户端,用于与 RESTful 服务或其他 HTTP 服务交互。相比于传统的 RestTemplate,WebClient 更加现代化,具有异步和…...
STM32笔记(串口IAP升级)
一、IAP简介 IAP(In Application Programming)即在应用编程, IAP 是用户自己的程序在运行过程中对 User Flash 的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产 品中的固件程序进行更新升级。 通常实…...
Ollama - 简化使用本地大语言模型
学习完用 Transformers 和 llama.cpp 使用本地大语言模型后,再继续探索如何使用 Ollama 跑模型。Ollama 让运行和管理大语言模型变得更为简单,它构建在 llama.cpp 之上,并有优化,性能表现同样不俗。下面罗列一下它的特点 从它的 …...
圆域函数的傅里叶变换和傅里叶逆变换
空域圆域函数的傅里叶变换 空域圆域函数(也称为空间中的圆形区域函数)通常指的是在二维空间中,以原点为中心、半径为 a a a的圆内取值为1,圆外取值为0的函数。这种函数可以表示为: f ( x , y ) { 1 if x 2 y 2 ≤ …...
智能交易模型的全景探索:量化技术的进步与未来
随着金融市场日益复杂化,量化交易模型在投资领域扮演着愈加重要的角色。这些模型通过数据驱动和技术创新,赋能投资者在高度波动的市场中寻找确定性收益点。本文将从技术进步、模型构建、应用优势和未来发展四个方面,探讨量化交易模型的演变与…...
mysql学习
1、 数据库的三范式是什么? 2、特点 - 永久性:从本质上来说数据库中的数据以计算机文件的方式存储在磁盘上- 结构性:数据不是杂乱无章的存储- 大量:只受到磁盘空间的影响 3、 Myisam与innodb的区别 4、mysql架构 开始编程语言进…...
小白新手村冒险之“烤”json串
JSON是什么? JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript的一个子集,但是JSON是独立于语言的文本格式,许多编…...
SQL基础入门—— 简单查询与条件筛选
在SQL中,查询是从数据库中获取数据的核心操作,而条件筛选是查询中不可或缺的一部分。通过使用条件筛选,我们可以精准地从大量数据中提取我们需要的信息。本节将详细讲解如何使用SQL进行简单查询与条件筛选,包含常见的条件运算符和…...
Java线程池种类及具体应用场景
Java线程池种类及具体应用场景 在实际开发中,选择合适的线程池类型至关重要,不同场景有不同的线程池需求。本文将结合线程池种类和具体应用示例,详细说明每种线程池的使用场景和适用情况。 一、固定大小线程池(FixedThreadPool&a…...
3D建筑模型的 LOD 规范
LOD(细节层次) 是3D城市建模中用于表示建筑模型精细程度的标准化描述不同的LOD适用于不同的应用场景 LOD是3D建模中重要的分级标准,不同层级适合不同精度和用途的需求。 从LOD0到LOD4,细节逐渐丰富,复杂性和精度也逐…...
掌上单片机实验室 — RT - Thread+ROS2 浅尝(26)
前面化解了Micro_ROS通讯问题,并在 RT-Thread Studio 环境下,使用Micro_ROS软件包中的例程,实现了STM32F411CE核心板和ROS2主机的通讯。之后还尝试修改例程 micro_ros_sub_twist.c ,实现了接收 turtle_teleop_key 所发出的 turtle…...
同步时序电路——描述
这部分要求了解一些触发器的状态方程: R-S触发器: D触发器: JK触发器: 时序电路:任一时刻的输出既与即刻输入有关(若有输入),还与电路当时的状态有关(和以前的输入有关),即电路具有记忆能力。 时…...
.net的winfrom程序 窗体透明打开窗体时出现在屏幕右上角
窗体透明, 将Form的属性Opacity,由默认的100% 调整到 80%,这个数字越小越透明(尽量别低于50%,不信你试试看)! 打开窗体时出现在屏幕右上角 //构造函数 public frmCalendarList() {InitializeComponent();//打开窗体&…...
反爬虫机制
许多网站会采取措施来防止爬虫频繁访问或抓取大量内容,这些措施被称为反爬虫机制。常见的反爬手段包括: IP 限制:通过检测频繁访问的 IP 地址,限制该 IP 的访问。 请求频率限制:网站可能通过检测请求间隔过短来判断是…...
ML 系列:第 31 节— 机器学习中的协方差和相关性
文章目录 一、说明二、协方差和相关性2.1 协方差的概念2.1 相关 三、有关关联的高级主题 (有关详细信息)3.1 相关性和独立性3.2 零相关性和依赖性示例 四、相关性和因果关系五、结论 一、说明 协方差量化了两个随机变量协同变化的程度。当一个变量的较高…...
registry 删除私有仓库镜像
原文链接:https://blog.csdn.net/yogima/article/details/122172744 如果需要彻底删除,只需进行register 磁盘删除镜像 彻底删除了,就可以到达彻底删除的目的。 如果只需要软删除,则只需进行通过API删除。 curl --header "Ac…...
初识java(3)
大家好,今天我们来讲讲我们的老伙计-变量,在哪一门编程语言中,变量的作用都是不可或缺的,那么下面我们就来详细了解一下java中的变量。 一.变量概念 在程序中,除了有始终不变的常量外,有些内容可能会经常…...
前端JavaScript(一)---基本介绍
Javascript是一种由Netscape(网景)的LiveScript发展而来的原型化继承的面向对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如Perl,遗留的速度问题,为客户提供更流畅的浏览效果。当时服务端需要对…...
【Linux打怪升级记 | 报错02】-bash: 警告:setlocale: LC_TIME: 无法改变区域选项 (zh_CN.UTF-8)
🗺️博客地图 📍1、报错发现 📍2、原因分析 📍3、解决办法 📍4、测试结果 1、报错发现 装好了CentOS操作系统,使用ssh远程登陆CentOS,出现如下告警信息: bash: 警告:setlocale…...
P1198 [JSOI2008] 最大数
P1198 [JSOI2008] 最大数https://www.luogu.com.cn/problem/P1198 牵制芝士:单调队列 思路: 我们的任务是找出一个区间最大值的 因为插入的数与上一次的答案有关 所以它是强制在线的(真无语了) 我们可以在每次插入时整一个叫…...
嵌入式串口通信 基于芯片STC8H8K64U 串口通信入门001
引言 差不多有四年的时间没有写csdn的原创文章了。一方面是由于家庭的角色转换,已为人母,家中的很多琐事牵绊了我。另一方面是因为工作确实也非常的忙碌。工作需要,也会不断地学习新的知识和复习旧的知识,思来想去,还是决心把工作中的经验心得和遇到的问题,和各位程序猿朋…...
基于Java的小程序电商商城开源设计源码
近年来电商模式的发展越来越成熟,基于 Java 开发的小程序电商商城开源源码,为众多开发者和企业提供了构建个性化电商平台的有力工具。 基于Java的电子商城购物平台小程序的设计在手机上运行,可以实现管理员;首页、个人中心、用户…...
[OpenHarmony5.0][Docker][环境]OpenHarmony5.0 Docker pull线上镜像方式构建编译环境
T. 已测试目录 主机类型主机版本Docker镜像版本结果WSL2Ubuntu22.04Ubuntu20.04PASSWSL2Ubuntu22.04Ubuntu18.04PASS R. 软硬件要求: 硬件: 设备容量备注硬盘>500G多版本系统测试,必须固态,否则编译卡死硬盘>300G单系统…...
计算机网络八股整理(二)
计算机网络八股整理(二) 应用层 1:dns的全称了解过吗? dns全称domain-name-system,翻译过来就是域名系统,是在计算机网络中将域名转换成ip地址的分布式数据库系统; 域名服务器的层级类似一个树…...
华财术_号卡分销平台讲解(四大运营商+手机卡)
【号卡分销平台对比讲解稿】 大家好,今天我们来详细对比几款热门的号卡分销平台,帮助您找到最适合自己的合作伙伴。我们将从佣金结算、数据安全、功能特性、用户体验以及适用人群等多个维度进行剖析,让您一目了然各平台的优劣。 一、号易号…...
fatal error in include chain (rtthread.h):rtconfig.h file not found
项目搜索这个文件 rtconfig 找到后将其复制粘贴到 你的目录\Keil\ARM\ARMCC\include 应该还有cJSON,rtthread.h和 等也复制粘贴下...
服务器记录所有用户docker操作,监控删除容器/镜像的人
文章目录 使用场景安装auditd添加docker审计规则设置监控日志大小与定期清除查询 Docker 操作日志查看所有用户,所有操作日志查看特定用户的 Docker 操作查看所有用户删除容器/镜像日志过滤特定时间范围内日志 使用场景 多人使用的服务器,使用的docker …...
电磁继电器
它的控制原理很简单,当我们给它的线圈接电,这个线圈就有了磁性,它上面的衔铁就会被吸引,这样小灯泡就会点亮 继电器于MOS管的差别在于,继电器可以很轻松的胜任高电压、大电流的场合 我们从外壳上可以看到 30VDC&#x…...
Hadoop生态圈框架部署(九)- Hive部署
文章目录 前言一、Hive部署(手动部署)下载Hive1. 上传安装包2. 解压Hive安装包2.1 解压2.2 重命名2.3 解决guava冲突 3. 配置Hive3.1 配置Hive环境变量3.2 修改 hive-site.xml 配置文件3.3 配置MySQL驱动包3.3.1 下在MySQL驱动包3.3.2 上传MySQL驱动包3.…...
thread_id_key != 0x7777(`fibers` 包与 Node.js 16 及以上版本存在兼容性问题)
文章目录 fibers4.0.3 与 node-v16.13.2-win-x64 的兼容性1. Node.js 版本兼容性2. 特定包版本 (fibers4.0.3)3. 解决方案和替代方案 结论解决方案 运行yarn serve 启动项目,就会弹出上述错误。 fibers4.0.3 与 node-v16.13.2-win-x64 的兼容性 要判断 fibers4.0.3…...
LabVIEW实现UDP通信
目录 1、UDP通信原理 2、硬件环境部署 3、云端环境部署 4、UDP通信函数 5、程序架构 6、前面板设计 7、程序框图设计 8、测试验证 本专栏以LabVIEW为开发平台,讲解物联网通信组网原理与开发方法,覆盖RS232、TCP、MQTT、蓝牙、Wi-Fi、NB-IoT等协议。 结合…...
hive的存储格式
1) 四种存储格式 hive的存储格式分为两大类:一类纯文本文件,一类是二进制文件存储。 Hive支持的存储数据的格式主要有:TEXTFILE、SEQUENCEFILE、ORC、PARQUET 第一类:纯文本文件存储 textfile: 纯文本文件存储格式…...
设置Mysql5.6允许外网访问
设置mysql用户支持外网访问步骤: 需要使用root权限登录mysql,更新mysql.user表,设置指定用户的Host字段为%,默认一般为127.0.0.1或者localhost。 1.登录数据库 1 mysql -u root -p 输入密码 1 mysql> use mysql; 2.查询hos…...
【智能制造-44】装配仿真
装配仿真包含以下功能模块: 零件建模与导入模块 功能描述: 能够创建简单的几何零件,如立方体、圆柱体、球体等基本形状。这对于一些标准件或者形状规则的零件来说,可以直接在装配仿真软件中生成,方便快捷。 支持多种…...
如何借助AI生成PPT,让创作轻松又高效
PPT是现代职场中不可或缺的表达工具,但同时也可能是令人抓狂的时间杀手。几页幻灯片的制作,常常需要花费数小时调整字体、配色与排版。AI的飞速发展为我们带来了革新——AI生成PPT的技术不仅让制作流程大大简化,还重新定义了效率与创意的关系…...
【工具变量】城市供应链创新试点数据(2007-2023年)
一、测算方式:参考C刊《经济管理》沈坤荣和乔刚老师(2024)的做法,使用“供应链创新与应用试点”的政策虚拟变量(TreatPost)表征。若样本城市为试点城市,则赋值为 1,否则为 0…...
线程的生命周期
计时等待(Timed Waiting)状态:这是等待状态的一种特殊情况,当线程调用带有超时参数的等待方法(如Thread.sleep(long millis)、Object.wait(long timeout)等)时会进入计时等待状态。例如,Thread.…...
Python入门(18)--实战项目
机器学习实战项目指南 🤖 项目概览 🌐 本项目是一个综合性的机器学习入门实战指南,通过实际案例展示机器学习项目的完整生命周期,包括数据处理、模型训练、评估和部署等关键环节。 1. 系统架构 🏗️ 1.1 核心组件 …...
DRM(数字权限管理技术)防截屏录屏----视频转hls流加密、web解密播放
提示:视频转hls流加密、web解密播放 需求:研究视频截屏时,播放器变黑,所以先研究的视频转hls流加密 文章目录 [TOC](文章目录) 前言一、工具ffmpeg、openssl二、后端nodeexpress三、web播放四、文档总结 前言 HLS流媒体协议&a…...
在linux上部署Tomcat方法
上传jdk,配置运行环境 解压jdk安装包 将jdk文件夹移动到/usr/local/jdk目录下 配置java环境变量vim /etc/profile 使环境变量生效,并且查看是否配置成功 安装tomcat,上传tomcat软件包 解压tomcat软件包 将tomcat解压文件移动到/usr/local/tomcat/下 启动…...
Git 使用问题与解决方案
Git 使用问题与解决方案 目录 常见错误及原因分析检查当前使用 HTTPS 或 SSH如何切换远程仓库到 SSHSSH 密钥的配置与验证错误解决步骤总结与参考 1. 常见错误及原因分析 错误提示 fatal: unable to access https://github.com/username/repository.git/: Failed to connect…...
LeetCode 热题 100_最大子数组和(13_53)(贪心算法 ||动态规划)
LeetCode 热题 100_最大子数组和(13_53) 题目描述:输入输出样例:题解:解题思路:代码实现(思路二(贪心算法 ||动态规划)): 题目描述: …...
Z2400023基于Java+Servlet+jsp+mysql的酒店管理系统的设计与实现 源码 调试 文档
酒店管理系统的设计与实现 1.摘要2.主要功能3. 项目技术栈运行环境 4.系统界面截图5.源码获取 1.摘要 本文介绍了一个基于Java的酒店管理系统,该系统采用Servlet、JSP、JDBC以及c3p0等技术构建,为酒店提供了一个全面的管理平台。该系统不仅适合酒店进行…...
T3 TensorFlow入门实战——天气识别
🍨 本文為🔗365天深度學習訓練營 中的學習紀錄博客🍖 原作者:K同学啊 | 接輔導、項目定制 一、前期准备 1. 导入数据 # Import the required libraries import numpy as np import os,PIL,pathlib import matplotlib.pyplot as …...
vue3 多种方式接受props,定义ref,reactive
定义props 1 第一种 interface AddType { dialogStudyVisible: boolean; } const props defineProps<AddType>(); 第二种 // const props defineProps({ // dialogStudyVisible:{ // type:Boolean, // default:false // } // }) 第三种 // const …...
15:00面试,15:06就出来了,问的问题有点变态。。。
从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到9月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%…...
vue3 数字滚动插件vue3-count-to
安装 npm i vue3-count-to -S 引入 import { CountTo } from vue3-count-to 使用 <countTo :startVal"0" :endVal"57.63" :decimals"0" :duration"3000"></countTo> 所有配置...
Android 手写签名板
文章目录 Android 手写签名板概述效果代码实现源码下载 Android 手写签名板 概述 手写签名板功能,支持图片保存、支持去除空白区域。 效果 生成图片效果: 代码实现 定义属性: <declare-styleable name"SignatureView">&…...
Java基础夯实——2.9 多线程如何共享数据
在 Java 多线程编程中,共享数据通过以下几种方式实现: 1. 使用共享对象 多个线程可以通过引用同一个对象来实现数据共享。例如: class SharedData {private int count;public synchronized void increment() {count;}public synchronized …...