Re常见简单密码

Re常见简单密码

起码没有Crypto专项那么柜物。。。

文章目录

  • Re常见简单密码
    • 1. RC4算法
    • 2. TEA算法
    • 3. XTEA算法
    • 4. XXTEA算法
    • 5. DASCTF strangeprograme
    • 参考

C语言stdint.h提供如下类型

int8_t 八位有符号整数
uint8_t 八位无符号整数
int16_t
int32_t
int64_t 64为有符号整数c_char_p char类型指针

1. RC4算法

RC4加密算法流程剖析结合CTF逆向签到 栀花谢了春红

RC4是对称加密中特殊的流加密算法,操作如下:

  1. 密钥调度KSA,初始化一个S表,用种子密钥填充另一个256字节的K表,用K表对S表进行初始置换。
  2. 伪随机字节流(密钥流)生成,使用KSA生成的状态数组S来生成伪随机字节流
  3. 通过伪随机字节流,也就是密钥流来与明文流进行异或
import binasciidef KSA(key):""" Key Scheduling Algorithm (KSA) """key_length = len(key)S = list(range(256))  # 对S表线性填充,一个字节范围0-255j = 0for i in range(256): # 打乱S盒j = (j + S[i] + key[i % key_length]) % 256S[i], S[j] = S[j], S[i]  # swapreturn Sdef PRGA(S):""" Pseudo-Random Generation Algorithm (PRGA) """# 伪随机数生成算法i = 0j = 0while True:i = (i + 1) % 256j = (j + S[i]) % 256S[i], S[j] = S[j], S[i]  # swapK = S[(S[i] + S[j]) % 256]yield K #生成器函数def RC4(key, plaintext):""" RC4 encryption/decryption """key = [ord(c) for c in key]S = KSA(key)keystream = PRGA(S)result = []for char in plaintext:val = ("%02x" % (ord(char) ^ next(keystream)))  # XOR and format as hexresult.append(val)return ''.join(result)def RC4_decrypt(key, ciphertext_hex):""" RC4 decryption """key = [ord(c) for c in key]S = KSA(key)keystream = PRGA(S)ciphertext_bytes = binascii.a2b_hex(ciphertext_hex) #16进制数据的字符串转包含二进制数据的字节字符串result = []for byte in ciphertext_bytes:val = chr(byte ^ next(keystream))  # XOR with keystream and convert to charresult.append(val)return ''.join(result)# 示例
key = 'woodpecker'
plaintext = "hello world!"
ciphertext = RC4(key, plaintext)
print(f"密文: {ciphertext}")#密文: 8f45c2f7528c3ae9624bb3a9
plaintext2=RC4_decrypt(key,ciphertext)
print("明文: %s"%(plaintext2))#明文: hello world!

2. TEA算法

Tiny Encryption Algorithm是一种分组密码算法,使用64位的明文分组和128位的密钥,通过不断增加的Delta(黄金分割率)值和Feistel结构进行加密,迭代次数一般为32轮。

在这里插入图片描述

C语言代码如下

#include <stdio.h>
#include <stdint.h>void encrypt (uint32_t *v,uint32_t *k ){uint32_t v0=v[0],v1=v[1],sum=0,i;uint32_t delta=0x9e3779b9;uint32_t k0=k[0],k1=k[1],k2=k[2],k3=k[3];for(i=0;i<32;i++){sum+=delta;v0+=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);v1+=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);} v[0]=v0;v[1]=v1;
}
void decrypt (uint32_t *v,uint32_t *k){uint32_t v0=v[0],v1=v[1],sum=0xC6EF3720,i;	//这里的sum是0x9e3779b9*32后截取32位的结果,截取很重要。uint32_t delta=0x9e3779b9;uint32_t k0=k[0],k1=k[1],k2=k[2],k3=k[3];for (i=0;i<32;i++){v1-=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);v0-=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);sum-=delta;} v[0]=v0;v[1]=v1;
}int main()
{uint32_t v[2]={1,2},k[4]={2,2,3,4};printf("加密前的数据:%u %u\n",v[0],v[1]);	//%u 以十进制形式输出无符号整数 encrypt(v,k);printf("加密后数据:%u %u\n",v[0],v[1]);decrypt(v,k);printf("解密后数据:%u %u\n",v[0],v[1]);return 0;
}

python代码如下

from ctypes import *def encrypt(v, k):v0 = c_uint32(v[0]) #明文左部分v1 = c_uint32(v[1])sum1 = c_uint32(0)delta = 0x9e3779b9for i in range(32):sum1.value += deltav0.value += ((v1.value << 4) + k[0]) ^ (v1.value + sum1.value) ^ ((v1.value >> 5) + k[1])v1.value += ((v0.value << 4) + k[2]) ^ (v0.value + sum1.value) ^ ((v0.value >> 5) + k[3])return v0.value, v1.valuedef decrypt(v, k):v0 = c_uint32(v[0])v1 = c_uint32(v[1])delta = 0x9e3779b9sum1 = c_uint32(delta * 32)for i in range(32):v1.value -= ((v0.value << 4) + k[2]) ^ (v0.value + sum1.value) ^ ((v0.value >> 5) + k[3])v0.value -= ((v1.value << 4) + k[0]) ^ (v1.value + sum1.value) ^ ((v1.value >> 5) + k[1])sum1.value -= deltareturn v0.value, v1.valueif __name__ == '__main__':a = [1, 2]k = [2, 2, 3, 4]print("加密前数据:", a)#8字节明文,16字节密钥,8字节密文res = encrypt(a, k)print("加密后的数据:", res)res = decrypt(res, k)print("解密后数据:", res)

3. XTEA算法

XTEA相较TEA增加了更多的密钥表,移位和异或操作,设计者是 Roger Needham, David Wheeler。

一般情况,明文8字节,密钥16字节,密文8字节

在这里插入图片描述

C语言代码

#include<stdio.h>
#include<stdint.h>void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]){unsigned int i;uint32_t v0=v[0],v1=v[1],sum=0,delta=0x9E3779B9;for(i=0;i<num_rounds;i++){v0+=(((v1<<4)^(v1>>5))+v1)^(sum+key[sum&3]);sum+=delta;v1+=(((v0<<4)^(v0>>5))+v0)^(sum+key[(sum>>11)&3]);}v[0]=v0;v[1]=v1;
}void decipher(unsigned int num_rounds,uint32_t v[2],uint32_t const key[4]){unsigned int i;uint32_t v0=v[0],v1=v[1],delta=0x9E3779B9,sum=delta*num_rounds;for(i=0;i<num_rounds;i++){v1-=(((v0<<4)^(v0>>5))+v0)^(sum+key[(sum>>11)&3]);sum-=delta;v0-=(((v1<<4)^(v1>>5))+v1)^(sum+key[sum&3]);} v[0]=v0;v[1]=v1;
}int main(){uint32_t v[2]={1,2};uint32_t const k[4]={2,2,3,4};unsigned int r=32;				//这里是加密轮数,自己设置 printf("加密前原始数据:%u %u\n",v[0],v[1]);encipher(r,v,k);printf("加密后原始数据:%u %u\n",v[0],v[1]);decipher(r,v,k);printf("解密后原始数据:%u %u\n",v[0],v[1]);return 0;
}

python代码如下

from ctypes import * 
def encrypt(v,k):v0=c_uint32(v[0])v1=c_uint32(v[1])sum1=c_uint32(0)delta=0x9e3779b9for i in range(32):v0.value+=(((v1.value<<4)^(v1.value>>5))+v1.value)^(sum1.value+k[sum1.value&3])sum1.value+=deltav1.value+=(((v0.value<<4)^(v0.value>>5))+v0.value)^(sum1.value+k[(sum1.value>>11)&3])return v0.value,v1.valuedef decrypt(v,k):v0=c_uint32(v[0])v1=c_uint32(v[1])delta=0x9e3779b9sum1=c_uint32(delta*32)for i in range(32):v1.value-=(((v0.value<<4)^(v0.value>>5))+v0.value)^(sum1.value+k[(sum1.value>>11)&3])sum1.value-=deltav0.value-=(((v1.value<<4)^(v1.value>>5))+v1.value)^(sum1.value+k[sum1.value&3])return v0.value,v1.valueif __name__=='__main__':a=[1,2]k=[2,2,3,4]print("加密前数据:",a)res=encrypt(a,k)print("加密后的数据:",res)res=decrypt(res,k)print("解密后数据:",res)

4. XXTEA算法

XXTEA,又称Corrected Block TEA,设计者是Roger Needham, David Wheeler。

XXTEA是一个非平衡Feistel网络分组密码,在可变长度块上运行,这些块是32位大小的任意倍数(最小64位)。

在这里插入图片描述
在这里插入图片描述

C语言代码

#include <stdio.h>
#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))void btea(uint32_t *v, int n, uint32_t const key[4])
{uint32_t y, z, sum;unsigned p, rounds, e;if (n > 1)            /* Coding Part */{rounds = 6 + 52/n;sum = 0;z = v[n-1];do{sum += DELTA;e = (sum >> 2) & 3;for (p=0; p<n-1; p++){y = v[p+1];z = v[p] += MX;}y = v[0];z = v[n-1] += MX;}while (--rounds);}else if (n < -1)      /* Decoding Part */{n = -n;rounds = 6 + 52/n;sum = rounds*DELTA;y = v[0];do{e = (sum >> 2) & 3;for (p=n-1; p>0; p--){z = v[p-1];y = v[p] -= MX;}z = v[n-1];y = v[0] -= MX;sum -= DELTA;}while (--rounds);}
}int main()
{uint32_t v[2]= {1,2};uint32_t const k[4]= {2,2,3,4};int n= 2; //n的绝对值表示v的长度,取正表示加密,取负表示解密// v为要加密的数据是两个32位无符号整数// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位printf("加密前原始数据:%u %u\n",v[0],v[1]);btea(v, n, k);printf("加密后的数据:%u %u\n",v[0],v[1]);btea(v, -n, k);printf("解密后的数据:%u %u\n",v[0],v[1]);return 0;
}

python代码

from ctypes import *def MX(z, y, sum1, k, p, e):return c_uint32(((z.value >> 5 ^ y.value << 2) + (y.value >> 3 ^ z.value << 4)) ^ ((sum1.value ^ y.value) + (k[(p & 3) ^ e.value] ^ z.value)))def btea(v, k, n, delta):if n > 1:sum1 = c_uint32(0)z = c_uint32(v[n - 1])rounds = 6 + 52 // ne = c_uint32(0)while rounds > 0:sum1.value += deltae.value = ((sum1.value >> 2) & 3)  # e都要32位哦for p in range(n - 1):y = c_uint32(v[p + 1])# v[p]=c_uint32(v[p]+c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[(p&3)^e.value]^z.value)))).value).valuev[p] = c_uint32(v[p] + MX(z, y, sum1, k, p, e).value).valuez.value = v[p]y = c_uint32(v[0])# v[n-1]=c_uint32(v[n-1]+c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[((n-1)&3)^e.value]^z.value)))).value).valuev[n - 1] = c_uint32(v[n - 1] + MX(z, y, sum1, k, n - 1, e).value).valuez.value = v[n - 1]rounds -= 1else: #decoding partsum1 = c_uint32(0)n = -nrounds = 6 + 52 // nsum1.value = rounds * deltay = c_uint32(v[0])e = c_uint32(0)while rounds > 0:e.value = ((sum1.value >> 2) & 3)  # e都要32位哦for p in range(n - 1, 0, -1):z = c_uint32(v[p - 1])# y[p]=c_uint32(v[p]-c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[(p&3)^e.value]^z.value)))).value).valuev[p] = c_uint32(v[p] - MX(z, y, sum1, k, p, e).value).valuey.value = v[p]z = c_uint32(v[n - 1])# v[n-1]=c_uint32(v[n-1]-c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[((n-1)&3)^e.value]^z.value)))).value).valuev[0] = c_uint32(v[0] - MX(z, y, sum1, k, 0, e).value).valuey.value = v[0]sum1.value -= deltarounds -= 1return vif __name__ == '__main__':v = [1, 2]k = [2, 2, 3, 4]delta = 0x9e3779b9n = 2"""n的绝对值表示v的长度,取正表示加密,取负表示解密v为要加密的数据是两个32位无符号整数k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位"""print("加密前数据:", v)res = btea(v, k, n, delta)print("加密后数据:", res)res = btea(v, k, -n, delta)print("解密后数据:", res)

5. DASCTF strangeprograme

彩笔虽然不懂,但复现一下总有好处的。

peid先查壳,发现.DASCTF段。

在这里插入图片描述

shift+F12查看字符串,跟踪Please input flag,按X进行交叉引用找到sub_415560,应当是main函数。

跟踪aDasctfIAmFakeB,看到DASCTF{I',27h,'am Fake But Why Look Like real?}

在这里插入图片描述

ctrl+s选择.DASCTF数据段跳转到loc_41D000,然后按x到sub_411064,再按x找到sub_413D50

在这里插入图片描述

跟踪sub_4111BD->sub_414E30->sub_411046->sub_414B90,

在这里插入图片描述

据说是SMC动态代码加密。

听说memcmp的IAT表给改了,在main函数的memcmp处打断点

在IDA外启动程序,IDA以附加进程形式开启调试,输入DASCTF{I'am Fake But Why Look Like real?}

跟踪一波,来到DASCTF段

在这里插入图片描述

按p创建函数,按F5,就是memcmp真正的逻辑

__int64 __cdecl sub_41D250(char *Str)
{__int64 v1; // rax__int64 v3; // [esp-8h] [ebp-24Ch]int j; // [esp+D0h] [ebp-174h]size_t i; // [esp+F4h] [ebp-150h]char *v6; // [esp+100h] [ebp-144h]int v7; // [esp+124h] [ebp-120h] BYREFint v8; // [esp+128h] [ebp-11Ch]int v9; // [esp+12Ch] [ebp-118h]int v10; // [esp+130h] [ebp-114h]char v11[260]; // [esp+13Ch] [ebp-108h] BYREFint savedregs; // [esp+244h] [ebp+0h] BYREFsub_4114D8(&unk_4250F3);v11[0] = -7;v11[1] = 77;v11[2] = 43;v11[3] = -68;v11[4] = 19;v11[5] = -35;v11[6] = 19;v11[7] = 98;v11[8] = -55;v11[9] = -4;v11[10] = -1;v11[11] = -119;v11[12] = 125;v11[13] = 79;v11[14] = -55;v11[15] = 15;v11[16] = 99;v11[17] = 29;v11[18] = 109;v11[19] = 82;v11[20] = 80;v11[21] = -3;v11[22] = 65;v11[23] = -29;v11[24] = 51;v11[25] = 118;v11[26] = 40;v11[27] = -105;v11[28] = 56;v11[29] = 54;v11[30] = -7;v11[31] = 107;v11[32] = -112;v11[33] = 57;v11[34] = 20;v11[35] = -125;v11[36] = 44;v11[37] = -30;v11[38] = 44;v11[39] = 31;memset(&v11[40], 0, 216);v7 = 0;v8 = 0;v9 = 0;v10 = 0;if ( j_strlen(Str) == 40 ){v6 = Str + 4;v7 = *(_DWORD *)Str;v8 = *((_DWORD *)Str + 1);sub_411541(&v7, &unk_422100);//tea*(_DWORD *)Str = v7;*((_DWORD *)Str + 1) = v8;for ( i = 2; i < j_strlen(Str) >> 2; i += 2 )//>>2相当于除以4{sub_411541(&v7, &unk_422100);//tea*(_DWORD *)Str = v7;*(_DWORD *)v6 = v8;*(_DWORD *)&Str[4 * i] ^= *(_DWORD *)Str;*(_DWORD *)&Str[4 * i + 4] ^= *(_DWORD *)v6;}for ( j = 0; j < 40; ++j ){HIDWORD(v1) = j;if ( Str[j] != v11[j] )//加密后的str要跟v11一样{LODWORD(v1) = 1;goto LABEL_12;}}LODWORD(v1) = 0;}else{LODWORD(v1) = 1;}
LABEL_12:v3 = v1;sub_41130C((int)&savedregs, (int)&unk_41D5CC);return v3;
}

sub_411541->sub_41D6F0,是个魔改TEA算法

int __cdecl sub_41D6F0(unsigned int *a1, _DWORD *a2)
{int result; // eaxunsigned int i; // [esp+DCh] [ebp-2Ch]int v4; // [esp+E8h] [ebp-20h]unsigned int v5; // [esp+F4h] [ebp-14h]unsigned int v6; // [esp+100h] [ebp-8h]//识别一下,v6->v[0],v5->v[1],v4->sum,delta->1640531527//函数类型是voidsub_4114D8(&unk_4250F3);v6 = *a1;v5 = a1[1];v4 = 0;for ( i = 0; i < 0x10; ++i ){v6 += (a2[1] + (v5 >> 5)) ^ (v4 + v5) ^ (*a2 + 16 * v5);v5 += (a2[3] + (v6 >> 5)) ^ (v4 + v6) ^ (a2[2] + 16 * v6);v4 -= 1640531527;}*a1 = v6;result = 4;a1[1] = v5;return result;
}

还原逻辑如下:

def tea_enc(v,k):v0=v[0]v1=v[1]delta=1640531527sum=0for i in range(0x10):v0 += (k[1] + (v1 >> 5)) ^ (sum + v1) ^ (k[0] + 16 * v1)v1 += (k[3] + (v0 >> 5)) ^ (sum + v0) ^ (k[2] + 16 * v0)sum -= deltav[0]=v0v[1]=v1return v

写出魔改TEA的解密代码

def tea_dec(v,k):v0=v[0]v1=v[1]delta=c_uint64(0x61C88647)sum=c_uint32(0)for i in range(16):sum.value=sum.value-delta.valuefor i in range(16):sum.value += delta.valuev1.value -= (k[3].value + (v0.value >> 5)) ^ (sum.value + v0.value) ^ (k[2].value + 16 * v0.value)v0.value -= (k[1].value + (v1.value >> 5)) ^ (sum.value + v1.value) ^ (k[0].value + 16 * v1.value)v[0]=v0v[1]=v1return v

程序F8至memset(&v11[40], 0, 216);后,查看v11

[0xBC2B4DF9, 0x6213DD13, 0x89FFFCC9, 0x0FC94F7D, 0x526D1D63, 0xE341FD50, 0x97287633, 0x6BF93638, 0x83143990, 0x1F2CE22C]
from ctypes import *
import binascii
import structk=[c_uint32(i) for i in [0x12345678, 0x09101112, 0x13141516, 0x15161718]]def tea_dec(v,k):v0=v[0]v1=v[1]delta=c_uint64(0x61C88647)sum=c_uint32(0)for i in range(16):sum.value=sum.value-delta.valuefor i in range(16):sum.value += delta.valuev1.value -= (k[3].value + (v0.value >> 5)) ^ (sum.value + v0.value) ^ (k[2].value + 16 * v0.value)v0.value -= (k[1].value + (v1.value >> 5)) ^ (sum.value + v1.value) ^ (k[0].value + 16 * v1.value)v[0]=v0v[1]=v1return vif __name__ == '__main__':v11=[0xBC2B4DF9, 0x6213DD13, 0x89FFFCC9, 0x0FC94F7D, 0x526D1D63, 0xE341FD50, 0x97287633, 0x6BF93638, 0x83143990, 0x1F2CE22C]for i in range(len(v11)):v11[i]=c_uint32(v11[i])for i in range(8,0,-2):v11[i + 1].value ^= v11[1].valuev11[i].value ^= v11[0].valuev11=tea_dec(v11, k)v11=tea_dec(v11, k)flag=[]for i in v11:for j in bytearray(binascii.a2b_hex(hex(i.value).replace("0x","")))[::-1]:#先转hex字符串,然后替换开头0x,然后转bytes,再转bytearray,调整一下顺序flag.append(chr(j))print("".join(flag))for i in v11:j=struct.pack('<I',i.value) #把int类型打包成小端序二进制字符串print(j.decode("utf-8"),end="")#DASCTF{I4TH0ok_I5S0ooFunny_Isnotit?????}

在这里插入图片描述

ps:使用lazyida注意,选中到最后一行的下一行,不然会缺数据,如下15缺失变成00

在这里插入图片描述

参考

  1. 解析 TEA 加密算法(C语言、python): 沐一 · 林

  2. CTF RE中的密码学 chillysome

  3. DASCTF-Strangeprograme_ok _Nickname

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

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

相关文章

定时器介绍

定时器介绍 STM32F103C8T6微控制器内部集成了多种类型的定时器&#xff0c;这些定时器在嵌入式系统中扮演着重要角色&#xff0c;用 于计时、延时、事件触发以及PWM波形生成、脉冲捕获等应用。下面是对STM32F103C8T6中几个定时器的 简单介绍&#xff1a;TIM1&#xff1a;这是一…

细数那些令人瞩目的内网穿透工具

在日常工作场景中&#xff0c;我们时常面临需要将本地网络中的特定端口&#xff08;如80、3306等&#xff09;对外开放&#xff0c;以便让远程用户或设备跨越局域网界限进行访问的需求。为实现这一目标&#xff0c;端口映射&#xff08;又称内网穿透&#xff09;技术显得尤为重…

Qt项目【上位机十字屏开发】

效果图 说明 重写 QWidget 中的 paintEvent() 处理绘图事件&#xff0c;废话不多说&#xff0c;上代码 源码 #ifndef MYWIDGETFORM_H #define MYWIDGETFORM_H#include <QWidget>namespace Ui { class myWidgetForm; }enum MYTYPE{SIZEWIDTH,SIZEHEIGHT,TOPWIDTH,TOPHE…

Spring 循环依赖解决方案

文章目录 1. 循环依赖的产生2. 循环依赖的解决模型3. 基于setter/Autowired 的循环依赖1_编写测试代码2_初始化 Cat3_初始化 Person4_ 回到 Cat 的创建流程5_小结 4. 基于构造方法的循环依赖5. 基于原型 Bean 的循环依赖6. 引人AOP的额外设计7. 总结 IOC 容器初始化bean对象的逻…

Java并发类的主要API方法-CountDownLatch和CyclicBarrier

1.概念介绍 CountDownLatch 是一个计数器&#xff0c;计数器的初始值由创建它时指定。每次调用 countDown() 方法时&#xff0c;计数器会减1&#xff0c;直到计数器值变为0时&#xff0c;所有调用 await() 的线程都会被唤醒继续执行。 CyclicBarrier 是 Java 中另一个常用的同…

渗透率超50%,新能源汽车已成中国制造新名片

近日&#xff0c;乘联会公布了最新一期全国乘用车市场分析报告。报告显示&#xff0c;今年7月&#xff0c;中国乘用车市场零售销量173.2万辆&#xff0c;批发销量195.6万辆&#xff1b;同期&#xff0c;新能源乘用车零售销量87.8万辆&#xff0c;批发销量94.5万辆。按此计算&am…

DC-4靶机渗透测试

一、靶机下载地址 https://www.vulnhub.com/entry/dc-4,313/ 二、信息收集 1、主机发现 # 使用命令 nmap 192.168.145.0/24 -sn | grep -B 2 "00:0C:29:43:49:A5" 2、端口扫描 # 使用命令 nmap 192.168.145.217 -p- -sV 3、指纹识别 # 使用命令 whatweb "…

顺序表各种接口的实现(C)

线性表 线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串…线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线。在物理结构上并不一定是连续的&#xff0c;线性表在物…

旋转字符串 | LeetCode-796 | 模拟 | KMP | 字符串匹配

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f579;️KMP算法练习题 LeetCode链接&#xff1a;796. 旋转字符串 文章目录 1.题目描述&#x1f351;2.题解&#x1fad0;2.1 暴力解法&#x1fad2;2.2 模拟…

c# 排序、强转枚举

List<Tuple<double,int>> mm中doble从小到大排序 mm本身排序 在C#中&#xff0c;如果你有一个List<Tuple<double, int>>类型的集合mm&#xff0c;并且你想要根据Tuple中的double值&#xff08;即第一个元素&#xff09;从小到大进行排序&#xff0c;同…

[Qt][对话框][下]详细讲解

目录 1.Qt内置对话框0.有哪些1.消息对话框 QMessageBox2.颜色对话框 QColorDialog3.⽂件对话框 QFileDialog4.字体对话框 QFontDialog5.输⼊对话框 QInputDialog6.进度条对话框 QProgressDialog 1.Qt内置对话框 0.有哪些 Qt提供了多种可复⽤的对话框类型&#xff0c;即Qt标准…

【启明智显技术分享】工业级HMI芯片Model3C/Model3A开发过程中问题记录笔记二

一、Model3C/Model3A芯片介绍 Model3C/Model3A是启明智显针对工业、行业以及车载产品市场推出的一款高性能、低成本的工业级HMI&#xff08;Human-Machine Interface&#xff0c;人机界面&#xff09;芯片。两颗芯片硬件PIN TO PIN&#xff1b;区别在于内置的PSRAM大小不同。该…

百度地图动态绘制台风轨迹

效果图如下: 台风测试数据获取 关键代码: /*** 动态绘制点和线*/drawMakerByAnimate () {const pointsMap = typhoneData.points;const title = typhoneData.tfid + typhoneData.name;if (!pointsMap || pointsMap.length === 0) {return;}if (this.markers.length > 0 &…

Godot《躲避小兵》实战之设置项目

通过之前的学习我们已经基本了解了godot的界面&#xff0c;知道如何创建项目以及节点。那么&#xff0c;从这一章节我们将进入godot官方给我们提供的一个2D游戏开发的小教程进行入手&#xff0c;这个游戏并不是我自己的作品&#xff0c;而是我通过学习完之后&#xff0c;对其进…

C#如何将自己封装的nuget包引入到项目中

问题 自己封装好了一个nuget包&#xff0c;但是不想上传到外网&#xff0c;想局域网使用&#xff0c;有两种方案 搭建私有nuget仓库放到离线文件夹中直接使用 第一种方式请请参考proget安装 下面主要是第二种方式 准备 新建类库项目 using System;namespace ClassLibrary…

数据结构--图(Graph)

定义 图&#xff08;Graph&#xff09;是由顶点的有穷非空集合和顶点之间边的集合组成的一种非线性表结构&#xff0c;通常表示为&#xff1a;G(V,E)&#xff0c;其中&#xff0c;G表示一个图&#xff0c;V是图G中顶点的集合&#xff0c;E是图G中边的集合。 顶点&#xff08;…

阿里云智能大数据演进

本文根据7月24日飞天发布时刻产品发布会、7月5日DataFunCon2024北京站&#xff1a;大数据大模型.双核时代实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a;徐晟 阿里云研究员/计算平台产品负责人 主要内容&#xff1a; Overview - 阿里云大数据 AI 产品…

经典算法题总结:数组常用技巧(双指针,二分查找和位运算)篇

双指针 在处理数组和链表相关问题时&#xff0c;双指针技巧是经常用到的&#xff0c;双指针技巧主要分为两类&#xff1a;左右指针和快慢指针。所谓左右指针&#xff0c;就是两个指针相向而行或者相背而行&#xff1b;而所谓快慢指针&#xff0c;就是两个指针同向而行&#xf…

【YOLO5 项目实战】(3)PCB 缺陷检测

欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【YOLO5 项目实战】(1)YOLO5 环境配置与测试 【YOLO5 项目实战】(2)使用自己的数据集训练目标检测模型 【YOLO5 项目实战】(3)PCB 缺陷检测 【YOLO5 项目实战】(3)PCB 缺陷检测 1. PCB 缺陷检…

vue-cli 中 配置 productionSourceMap 为 false 失效?

背景 最近 发现 vuecli 构建的 项目中配置的 productionSourceMap 为 false 后 &#xff0c;生产代码 还是能够看到 sourceMap 文件 。 原因 生效前提条件 得设置 NODE_ENV 为 production 才会生效&#xff01; 解决 直接修改生产环境的配置 NODE_ENV 为 production 直接覆…