当前位置: 首页 > news >正文

【2021.12.25】ctf逆向中常见加密算法和编码识别

【2021.12.25】ctf逆向中常见加密算法和编码识别(含exe及wp)

文章目录

  • 【2021.12.25】ctf逆向中常见加密算法和编码识别(含exe及wp)
    • 0、前言
    • 1、基础加密手法
    • 2、base64
      • (1)原理:
      • (2)base64完整编码过程
      • (3)base64完整解码过程
      • (4)特殊情况
      • (5)base64加解密代码
      • (6)base64在ctf中的变换
      • (7)变换码表之后的base解法:
      • (8)base58
      • (9)练习
    • 3、TEA
      • (1)简介
      • (2)TEA加解密代码
      • (3)TEA扩展:XTEA加密
    • 4、RC4
      • (1)简介
      • (2)加密过程
      • (3)RC4加解密代码
      • (4)RC4逆向
      • (5)逆向RC4算法技巧
      • (6)练习
    • 5、MD5
      • (1)简介
      • (2)特点
      • (3)运用
      • (4)ctf逆向中的使用
    • 6、总结

0、前言

在对数据进行变换的过程中,除了简单的字节操作之外,还会使用一些常用的编码加密算法,因此如果能够快速识别出对应的编码或者加密算法,就能更快的分析出整个完整的算法。

CTF 逆向中通常出现的加密算法包括 base64、TEA、AES、RC4、MD5 等。

1、基础加密手法

简单位运算

位运算C语言符号意义
左移<<一般是位左移,低位补零
右移>>一般是位右移,有符号数高位补符号位,无符号数高位补0
异或^按位比较,相同位取0,不同位取1
&按位比较,全为1时取1,否走取0
|按位比较,全为0时取0,否则取1
~按位取反

简单加密类型

基础加密算法简易公式意义
凯撒加密Y=X+a任意值X经过偏移为a的移位变换为Y
仿射加密Y = aX+b与上面类似

2、base64

Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。其码表有64个字符。

base64码表

加密的数据分为3个字节一组、6位一段;其中6位的含义是2的6次方=64,可以用64个码表字符表示。

(1)原理:

3个字节一组,将 3 字节的数据,(字符对应Ascll码)先后放入一个 24位的缓冲区中,先来的字节占高位。

3个字节24位从高到低平分成4段,每段6位,

用这6位二进制为代表的数字在base表中查找对应位置的字符。

(2)base64完整编码过程

假设要编码的字符串长度是3的倍数。

image-20210907185026475

(3)base64完整解码过程

假设要解码的字符串长度是4的倍数。

image-20210907185139929

(4)特殊情况

加密字符长度除以3余1 ,则最后一组只有1个字节8位,将8位二进制后续以0填充至12位,(6的倍数),分成两段,查表获得两个字符,再添加‘==’,凑齐4个字符,完整演示如下。

image-20210907185307314

加密字符长度除以3余2,则最后一组只有2个字节16位,将16位二进制后续以0填充至18位,(6的倍数),分成3段,查表获得三个字符,再添加‘=’,凑齐4个字符,完整演示如下。

image-20210907185442061

(5)base64加解密代码

–C语言–

环境:win10

编译:VC++6.0

加密

#include<stdio.h>
#include<string.h>
#include<stdlib.h>char a[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char s[100];
int i,j;void jiami(char x,char y,char z){s[j]=a[x>>2];s[j+1]=a[(x<<4|y>>4)&0x3f];s[j+2]=a[(y<<2|z>>6)&0x3f];s[j+3]=a[z&0x3f];
}int main(){int len;char str[100];printf("base64需要加密的字符串:");gets(str);len=strlen(str);for(i=0,j=0;i<=len-3;i+=3,j+=4){jiami(str[i],str[i+1],str[i+2]);}if(len%3==1){s[j]=a[str[len-1]>>2];s[j+1]=a[str[len-1]<<4&0x3f];s[j+2]='=';s[j+3]='=';}if(len%3==2){s[j]=a[str[len-2]>>2];s[j+1]=a[(str[len-2]<<4|str[len-1]>>4)&0x3f];s[j+2]=a[(str[len-1]<<2)&0x3f];s[j+3]='=';}printf("\n加密之后:");puts(s);printf("\n");system("pause");return 0;
}

解密

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char s[100];
int i,j;
char a[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";void jiemi(int a,int b,int c,int d)
{s[j]=a<<2|b>>4;s[j+1]=b<<4|c>>2;s[j+2]=c<<6|d;
}int main()
{int len,len1;int str1[100];char str[100];printf("base64需要解密的字符串:");gets(str);len=strlen(str);for(i=0;i<len;i++)for(j=0;j<64;j++)if(str[i]==a[j]){str1[i]=j;len1=i+1;	}	for(i=0,j=0;i<=len1-4;i+=4,j+=3)jiemi(str1[i],str1[i+1],str1[i+2],str1[i+3]);if(len1%4==2)s[j]=str1[i]<<2|str1[i+1]>>4;if(len1%4==3){s[j]=str1[i]<<2|str1[i+1]>>4;s[j+1]=str1[i+1]<<4|str1[i+2]>>2;}printf("\n解密之后:");puts(s);putchar('\n');system("pause");return 0;
}

–python–

环境:win10

编译:VScode-python3

python的话就比较简单了,直接调库即可。

image-20210907185856813

image-20210907190143736

(6)base64在ctf中的变换

  1. 替换base64码表

  2. 改写编码过程

    (1)编码之后每一位进行偏移或仿射

    (2)编码时3字节分4段,每段不固定6位, 可以分成 5位 6位 6位 7位 共24位 3字节

    (3)编码不固定3字节一组,也可以4字节32位, 分为6位 6位 7位 7位 6位,共32位

常见base家族

base32,码表32个字符,8个字节一组、5位一段;2的5次方=32

base16,码表16个字符,1个字节一组、4位一段;2的4次方=16

(7)变换码表之后的base解法:

C语言脚本: 直接替换码表即可

python脚本:将编码中字符,与新base64码表和原始base64码表,作一一映射的替换, 再调库进行正常base64解码(原始码表)

import base64
import string
s = "pCNxpTJ2d3d5nPoQnSAAnQBel4lihldkikV78nQ="#base64编码str1 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/"#base64新的码表
str2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"#base64原始码表trantab  = str.maketrans(str1,str2)#maketrans方法 返回str1与str2一一映射表
#print(type(trantab),trantab )s_base64 = s.translate(trantab)#translate方法,s的每一个字符,通过上面trantab一一映射表,替换为另一字符串s_new = base64.b64decode(s_base64).decode('utf-8')
print(s_new)

image-20210907190713710

(8)base58

base58,码表58个字符,将三个字节数值 连起来看做256进制, 再将其转换为4个58进制,对应码表查找字符。

image-20210907231542080

图片参考:编码算法-Base58

(9)练习

base64换表练习

链接:https://pan.baidu.com/s/11Mm_qRxgplp-pKLSWnXPlg
提取码:wqpf

base64算法变换练习

链接:https://pan.baidu.com/s/1ZrsfrSJauYbTAnFd_X0Ang
提取码:qh6u

3、TEA

(1)简介

微型加密算法(Tiny Encryption Algorithm,TEA)是一种易于描述和执行的块密码,通常只需要很少的代码就可实现。由剑桥大学计算机实验室的David Wheeler和Roger Needham于1994年发明。

它是一种分组密码算法,其明文密文块为64比特密钥长度为128比特

TEA算法利用不断增加的Delta(黄金分割率)值作为变化,使得每轮的加密是不同,该加密算法的迭代次数可以改变,建议的迭代次数为32轮。QQ使用此加密技术,加密轮数为16轮。

明文密文块为64比特:一般两个4字节数 (int型)

密钥长度为128比特:一般4个四字节数(int型)

整体的加密过程如下图

image-20210907232940561

图片参考:TEA、XTEA、XXTEA加密解密算法

(2)TEA加解密代码

环境:win10

编译:VC++6.0

建议代码结合上图一起分析。

加密

#include<stdio.h>
void encode(unsigned int* v,unsigned int *k)
{unsigned int v0=v[0],v1=v[1];unsigned int k0=k[0],k1=k[1],k2=k[2],k3=k[3];unsigned int delta=0x9e3779b9;int i;unsigned int sum=0;for(i=0;i<32;i++)          //核心加密算法,建议32轮,最低16轮{sum+=delta;v0+=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);     //r<<4/r*16v1+=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);}v[0]=v0;v[1]=v1;
}
int main()
{//明文,必须是8字节的倍数,不够需要程序补全,参考base64方法unsigned int m[2]={1,2}; unsigned int k[4]={2,2,3,4};//密钥随便 一定是128位,即4个4字节数encode(m,k);printf("%d %d\n",m[0],m[1]);return 0;
}

解密

#include<stdio.h>
#include<windows.h>void decode(unsigned int* v,unsigned int *k)
{unsigned int v0=v[0], v1=v[1], sum=0xC6EF3720, i;  //由加密轮数而算出unsigned int delta=0x9e3779b9;                     unsigned int 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()
{unsigned int c[2]={1347371722,925494771}; //密文,两字节一组unsigned int k[4]={2,2,3,4};//密钥随便 一定是128位,即4个4字节数decode(c,k);printf("%d %d\n",c[0],c[1]);return 0;
}

(3)TEA扩展:XTEA加密

XTEA加密和TEA加密基本类似,只是多了一点点,对比一下代码即可发现。

环境:win10

编译:VC++6.0

加密

#include <stdio.h>   /* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */  void encipher(unsigned int num_rounds, unsigned int v[2], unsigned int key[4]) 
{  unsigned int i;  unsigned int v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;  for (i=0; i < num_rounds; i++) {  sum += delta;  v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);  v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);  }  v[0]=v0; v[1]=v1;  
}  int main()  
{  unsigned int v[2]={1,2};  unsigned int k[4]={2,2,3,4};  unsigned int r=32;//num_rounds建议取值为32  // v为要加密的数据是两个32位无符号整数  // k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位  printf("加密前原始数据:%u %u\n",v[0],v[1]);  encipher(r, v, k);  printf("加密后的数据:%u %u\n",v[0],v[1]);   return 0;  
}  

解密

#include <stdio.h> /* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */  void decipher(unsigned int num_rounds, unsigned int v[2], unsigned int key[4])
{  unsigned int i;  unsigned int v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;  for (i=0; i < num_rounds; i++) {  sum -= delta;  v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);  v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);  }  v[0]=v0; v[1]=v1;  
}  int main()  
{  unsigned int c[2]={1345390024,2801624574};  unsigned int k[4]={2,2,3,4};  unsigned int r=32;//num_rounds建议取值为32  // v为要加密的数据是两个32位无符号整数  // k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位  printf("解密前原始数据:%u %u\n",c[0],c[1]);  decipher(r, c, k);  printf("解密后的数据:%u %u\n",c[0],c[1]);  return 0;  
}  

4、RC4

(1)简介

百度百科:RC4

RC4(来自 Rivest Cipher 4 的缩写)是一种流加密算法密钥长度可变。它加解密解密使用相同的密钥,因此也属于对称加密算法。RC4 是有线等效加密(WEP)中采用的加密算法,也曾经是 TLS可采用的算法之一。

特点:

名称特点
秘钥长度可变,通常小于256字节
密钥流指S盒,长度256Byte,初始化为0~255序列,然后根据秘钥K搅乱
明文长度任意,明文只一次异或加密

(2)加密过程

image-20210908001318799

注意看加密过程,明文就一个异或加密

只是密钥流要当时生成,加密解密的密钥流都是一样的

完整加密过程

结合上图

image-20210908001437128

注意: 加密前,生成的密钥流s盒,加密后密钥流s盒会发生改变,所以解密时,用的密钥流s盒是初始化之后但加密前的,即上图第一步之后生成的s盒。

(3)RC4加解密代码

先初始化秘钥

image-20210908001536375

再进行加解密,(用的秘钥都是上述代码初始化出来的)

image-20210908001710735

完整加密代码

环境:win10

编译:VC++6.0

main函数有通过RC4加解密的整个过程

//程序开始
#include<stdio.h>
#include<string.h>/*初始化函数*/
//参数1:传入长度256的unsigned char型数组首地址
//参数2:密钥,其内容可以随便定义:char key[256];
//参数3是密钥的长度,Len = strlen(key);
void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
{int i = 0, j = 0;char k[256] = { 0 };unsigned char tmp = 0;for (i = 0; i<256; i++){s[i] = i;//初始化s盒,0~255k[i] = key[i%Len];}for (i = 0; i<256; i++)//将s盒打乱{j = (j + s[i] + k[i]) % 256;tmp = s[i];//交换s[i]和s[j]s[i] = s[j];  s[j] = tmp;}
}/*加解密*/
//参数1:是上边rc4_init函数中,被搅乱的S-box;
//参数2:是需要加密/解密的数据data;
//参数3:data的长度.
void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
{int i = 0, j = 0, t = 0;unsigned long k = 0;unsigned char tmp;for (k = 0; k<Len; k++){i = (i + 1) % 256;j = (j + s[i]) % 256;tmp = s[i];s[i] = s[j];//交换s[x]和s[y]s[j] = tmp;t = (s[i] + s[j]) % 256;Data[k] ^= s[t];}
}int main()
{unsigned char s[256] = { 0 }, s2[256] = { 0 };//S-boxchar key[256] = { "justfortest" };unsigned char pData[512] = "Hello World";unsigned long len = strlen((char*)pData);int i;printf("pData=%s\n", pData);printf("key=%s,length=%d\n\n", key, strlen(key));rc4_init(s, (unsigned char*)key, strlen(key));//已经完成了初始化printf("完成对S[i]的初始化,如下:\n\n");for (i = 0; i<256; i++){printf("%02X", s[i]);if (i && (i + 1) % 16 == 0)putchar('\n');}printf("\n\n");for (i = 0; i<256; i++)//用s2[i]暂时保留经过初始化的s[i],很重要的!!!{s2[i] = s[i];}printf("已经初始化,现在加密:\n\n");rc4_crypt(s, (unsigned char*)pData, len);//加密for(i=0;pData[i];i++){printf("0x%x,",pData[i]);}//printf("pData=%s\n\n", pData);printf("\n");printf("已经加密,现在解密:\n\n");//rc4_init(s,(unsignedchar*)key,strlen(key));//初始化密钥rc4_crypt(s2, (unsigned char*)pData, len);//解密printf("pData=%s\n\n", pData);return 0;
}//程序完

(4)RC4逆向

上述可以看出RC4算法,加密和解密是一样的流程

先初始化密钥流S盒,再通过初始化的密钥流S盒对数据进行异或加密/解密

所以逆向RC4算法:找到密钥、加密之后的数据,用来跑一边解密脚本

(5)逆向RC4算法技巧

image-20210908002309988

image-20210908002304517

通过上面两张图可以看到:

密文=明文^密钥流

所以!明文=密文^密钥流

即密钥固定时,每次加密生成的秘钥流是固定的

**解密难点:**密钥流未知

技巧:

我们可以通过选择明文攻击

即输入一串已知明文,调试获取加密之后的密文

这样就已知了明文和对应密文

所以可求:密钥流=已知明文^对应密文

然后根据原始密文

可求得:原始明文=原始密文^密钥流

(6)练习

RC4练习

链接:https://pan.baidu.com/s/1nblRiYkSFewKRyulSirUXg
提取码:ffyq

5、MD5

(1)简介

MD5 消息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个 128 位(16 字节)的散列值(hash value),用于确保信息传输完整一致

(2)特点

1、无论加密数据多大多小,都只生成长度一样的散列值(一般是128位,16字节)

2、相同的数据,随时生成的散列值都一致,但只要数据发生一点变化,生成的散列值差别巨大

3、MD5本身不可逆

(3)运用

1、密码管理,输入密码后进行md5加密然后与数据库中的md5值对比(易受到md5撞库攻击)

2、电子签名,确保数据传输过程中数据更改

(4)ctf逆向中的使用

在线md5加密网址:https://www.somd5.com/

6、总结

ctf逆向中的加密算法坑定不止上述这些,只是说通过这些简单的加密算法,学习,进阶,再难的算法都是从基础算法变换而来的,好比万丈高楼平地起!加油!

相关文章:

【2021.12.25】ctf逆向中常见加密算法和编码识别

【2021.12.25】ctf逆向中常见加密算法和编码识别&#xff08;含exe及wp&#xff09; 文章目录【2021.12.25】ctf逆向中常见加密算法和编码识别&#xff08;含exe及wp&#xff09;0、前言1、基础加密手法2、base64&#xff08;1&#xff09;原理&#xff1a;&#xff08;2&#…...

【数据结构初阶】堆排序

目录 前言 概念 堆排序的实现 1.建堆 &#xff08;1&#xff09;堆向上调整算法 &#xff08;2&#xff09;堆的向下调整算法 2. 利用堆删除思想来进行排序 3.堆排序的时间复杂度 4.源码 总结 前言 前边我们学习了堆的实现&#xff0c;对堆的每个接口都进行了详细的讲…...

Day5: platformDriver-1

Platform Driver (1) Linux kernel中大部分设备可以归结为平台设备&#xff0c;因此大部分的驱动是平台驱动&#xff08;patform driver&#xff09; 什么是平台设备 平台设备是linux的设备模型中一类设备的抽象。 内核中的描述&#xff1a; Platform devices are devices t…...

开发手册——一、编程规约_7.控制语句

这篇文章主要梳理了在java的实际开发过程中的编程规范问题。本篇文章主要借鉴于《阿里巴巴java开发手册终极版》 下面我们一起来看一下吧。 1. 【强制】在一个 switch 块内&#xff0c;每个 case 要么通过 break / return 等来终止&#xff0c;要么注释说明程序将继续执行到哪…...

python每日学9 : windows上配置gitee的远程仓库,git的初步使用

在开发中&#xff0c;如果遇到复杂的项目&#xff0c;使用版本控制是非常有必要的&#xff0c;如果涉及到多端开发&#xff0c;那么还需要使用远程仓库。本文作个简单记录&#xff0c;记录下git初步使用。 1 下载与安装 git还有几个ui版本&#xff0c;但是开始使用的话&#…...

精确率与召回率,ROC曲线与PR曲线

精确率与召回率&#xff0c;ROC曲线与PR曲线 在机器学习的算法评估中&#xff0c;尤其是分类算法评估中&#xff0c;我们经常听到精确率(precision)与召回率(recall)&#xff0c;ROC曲线与PR曲线这些概念&#xff0c;那这些概念到底有什么用处呢&#xff1f; 首先&#xff0c…...

现代操作系统——Linux架构与学习

小白的疑惑 在我决定从事嵌入式&#xff08;应用层&#xff09;方面的工作时&#xff0c;我查询了大量资料该如何学习&#xff0c;几乎所有观点不约而同的都指向了学习好Linux&#xff0c;大部分工作都是在Linux环境下来进行工作的。于是我雄心勃勃的去下载Linux&#xff0c;可…...

中文代码82

PK 嘚釦 docProps/PK 嘚釦羸 r docProps/app.xml潙蚽?勶曻Q顗濔S? 錞礖剅D柍珘m?鳞?ぷ辷f硌?2?upc厭Y樐8 rU y搪m眾&a?珪?紓 玺鶋瑣襚? ?i嘲rN?布倖儇?攊橌??嚗猝)芻矂2吟腊K湞?CK臶>鸘\?ΔF滋齢q旮T?桀?;偉 A軥v蕯朾偤佷3?е…...

顺序表(一篇带你掌握顺序表)

目录 一、顺序表是什么 1.1 概念 1.2 分类 1.3 结构 二、顺序表的基本操作 2.1 前绪准备 2.2 初始化 2.3 扩容 2.5 尾插 2.6 打印 2.7 尾删 2.8 头插 2.9 头删 2.10 在pos位置插入 2.11 删除pos位置的数据 2.12 查找 三、完整代码 3.1 Test.c文件 3.2 SeqList.h…...

【SpringCloud】SpringCloud教程之Feign实战

目录前言SpringCloud Feign远程服务调用一.需求二.两个服务的yml配置和访问路径三.使用RestTemplate远程调用(order服务内编写)四.构建Feign(order服务内配置)五.自定义Feign配置(order服务内配置)六.Feign配置日志(oder服务内配置)七.Feign调优(order服务内配置)八.抽离Feign前…...

嵌入式linux必备内存泄露检测神器

Valgrind介绍 Valgrind是一个可移植的动态二进制分析工具集&#xff0c;主要用于发现程序中的内存泄漏、不合法内存访问、使用未初始化的内存、不正确的内存释放以及性能问题等&#xff0c;可在Linux和Mac OS X等平台上使用。 Valgrind由多个工具组成&#xff0c;其中最常用的…...

设计模式之行为型模式

四、行为型模式 行为型模式用于描述程序在运行时复杂的流程控制&#xff0c;即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务&#xff0c;它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象行为模式&#xff0c;前者采用继承机制来在…...

解密 三岁的三岁到底为什么叫做三岁?

机缘 那一年&#xff0c;一次奇奇怪怪的挫折与一次奇奇怪怪的成长。 在学习Python的路上总觉得少了点什么&#xff0c;是心情&#xff1f;是机遇&#xff1f;还是力量&#xff1f; 都不是又都是&#xff01; 缺少一个实践和记忆的平台 记性不好是硬伤 前一天学的下一秒就忘记了…...

id选择器

id选择器可以为特定的id的标签进行css美化 使用方法&#xff1a; 标签内设好 id值&#xff0c; CSS的id选择器以“#id名”来调用 注意 所有标签都有id值id属性值类似于身份证号码&#xff0c;在一个页面中是唯一的值&#xff0c;不可重复一个标签上只能有一个id属性值一个id属性…...

《科技之巅3》读书笔记

文章目录书籍信息人工智能&#xff0c;“吃一堑长一智”的机器人机交互&#xff0c;为解决“交流障碍”问题而生硬件与算法&#xff0c;好马还需好鞍模式创新&#xff0c;赋予技术新的定义云与数据共享&#xff0c;灵活应对信息的爆发式增长“机器人”&#xff0c;从电影和小说…...

18.用于大型程序的工具

文章目录用于大型程序的工具18.1异常处理18.1.1抛出异常栈展开栈展开过程中对象被自动销毁析构函数与异常异常对象18.1.2捕获异常查找匹配的处理代码重新抛出捕获所有异常的处理代码18.1.3函数try语句块与构造函数18.1.4noexcept异常说明违反异常说明异常说明的实参noexcept运算…...

mysql一主键uuid和自增的选择

文章目录 1.自增ID的优缺点1.1 优点1.2 缺点1.3 不适合以自增ID主键作为主键的情况2.UUID作为主键2.1 介绍2.2 优点2.3 缺点3.有序UUID作为主键3.1 介绍3.2 演示使用3.2.1 前提知识3.2.1.1 数据类型 - binary3.2.1.2 函数 - hex()3.2.1.3 函数 - unhex()3.2.2 数据库层3.2.3 JA…...

【EDA工具使用】——VCS和Verdi的联合仿真的简单使用

目录 1.芯片开发所需的工具环境 2.编译仿真工具 3.三步式混合编译仿真&#xff08;最常用&#xff09;​编辑 4.两步式混合编译仿真​编辑 5.VCS的使用 ​6.verdi的使用 1.产生fsdb文件的两种方法​编辑 1.芯片开发所需的工具环境 2.编译仿真工具 3.三步式混合编译仿真…...

【Java学习笔记】4.Java 对象和类

前言 本章介绍Java的对象和类。 Java 对象和类 Java作为一种面向对象语言。支持以下基本概念&#xff1a; 多态继承封装抽象类对象实例方法重载 本节我们重点研究对象和类的概念。 对象&#xff1a;对象是类的一个实例&#xff08;对象不是找个女朋友&#xff09;&#x…...

39. 实战:基于api接口实现视频解析播放(32接口,窗口化操作,可导出exe,附源码)

目录 前言 目的 思路 代码实现 需要导入的模块 1. 导入解析网站列表&#xff0c;实现解析过程 2. 设计UI界面 3. 设置窗口居中和循环执行 4. 注意事项 完整源码 运行效果 总结 前言 本节将类似34. 实战&#xff1a;基于某api实现歌曲检索与下载&#xff08;附完整…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...