在OpenSSL中添加自定义加密算法

2023-11-06

OpenSSL中添加自定义加密算法

 

1.加密算法的加载... 1

2.密码算法接口的定义... 4

3.示例... 8

 

1.加密算法的加载

在调用加密算法之前,通过调用OpenSSL_add_all_algorithms来加载加密算法函数和单向散列算法函数

void OpenSSL_add_all_algorithms(void)

{

       OpenSSL_add_all_ciphers();  /* 加载加密算法 */

       OpenSSL_add_all_digests(); /* 加载单向散列函数 */

}

 

void OpenSSL_add_all_ciphers(void)函数实现如下:

 

void OpenSSL_add_all_ciphers(void)

       {

       EVP_add_cipher(EVP_rc2_cfb());

       ......

       PKCS12_PBE_add();

       PKCS5_PBE_add();

       }

/* 这个过程的主要任务是向全局变量,static LHASH *names_lh,注册加密算法,如果添加了新的加密算法,必需向names_lh注册。 */

 

以下是IDEA算法的接口:

#ifndef NO_IDEA

       EVP_add_cipher(EVP_idea_ecb());      /*添加EBC加密模式 */

       EVP_add_cipher(EVP_idea_cfb());       /*添加CFB加密模式 */

       EVP_add_cipher(EVP_idea_ofb());       /*添加OCF加密模式 */

       EVP_add_cipher(EVP_idea_cbc());      /*添加CBC加密模式 */

       EVP_add_cipher_alias(SN_idea_cbc,"IDEA");     /*添加cbc加密算法的别名 IDEA */

       EVP_add_cipher_alias(SN_idea_cbc,"idea"); /*添加cbc加密算法的别名 idea */

#endif

 

在包括IDEA加密算法的情况下,OpenSSL将会选择IDAE加密算法模块!

 

下面来看看EVP_add_cipher函数是怎么实现的,

int EVP_add_cipher(EVP_CIPHER *c)

{

       int r;

 

       r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(char *)c);

       if (r == 0) return(0);

       r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(char *)c);

       return(r);

}

 

/* 向全决变量names_lh 注册 obj_name_types 变量的过程 */

int OBJ_NAME_add(const char *name, int type, const char *data)

       {

       OBJ_NAME *onp,*ret;

       int alias;

 

       if ((names_lh == NULL) && !OBJ_NAME_init()) return(0);

 

       alias=type&OBJ_NAME_ALIAS;

       type&= ~OBJ_NAME_ALIAS;

 

       onp=(OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));

       if (onp == NULL)

              {

              /* ERROR */

              return(0);

              }

 

       onp->name=name;

       onp->alias=alias;

       onp->type=type;

       onp->data=data;

 

       ret=(OBJ_NAME *)lh_insert(names_lh,onp);

       if (ret != NULL)

              {

              /* free things */

              if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))

                     {

                     /* XXX: I'm not sure I understand why the free

                      * function should get three arguments...

                      * -- Richard Levitte

                      */

                     sk_NAME_FUNCS_value(name_funcs_stack,ret->type)

                            ->free_func(ret->name,ret->type,ret->data);

                     }

              OPENSSL_free(ret);

              }

       else

              {

              if (lh_error(names_lh))

                     {

                     /* ERROR */

                     return(0);

                     }

              }

       return(1);

       }

 

names_lh LHASH的全局变量,用于维护obj_name_types的类型的变量。(在crypt/objects/o_names.c中定义)

 

crypt/objects/obj_dat.h)相关的全局变量

static unsigned char lvalues[2896] 全局变量,已经初始化,存放了OpenSSL所有Object的相关信息。

nid_objs  ASN1_OBJECT结构的数组全局变量,已经初始化,记录了所有OpenSSL用到的类型的名字

static ASN1_OBJECT *sn_objs[NUM_SN] 全局变量,已经初始化。

static ASN1_OBJECT *ln_objs[NUM_LN] 全局变量,已经初始化。

 

crypt/object/objects.h 中定义的结构

typedef struct obj_name_st

{

       int type;

       int alias;

       const char *name;

       const char *data;

} OBJ_NAME;

 

注意:crypto/objects 目录下面维护整个OpenSSL模块化的重要的程序,下面逐个做出介绍。

objects.txt 按照一定的语法结构,定义了SN_base, LN_base, NID_baseOBJ_base。经过perl程序objects.pl通过命令perl objects.pl objects.txt obj_mac.num obj_mac.h 处理后,生成了obj_mac.num obj_mac.h两个文件。

obj_mac.num 用来查阅 OBJ_baseNID_base之间的对应关系。

obj_mac.h 用来提供c语言类型SN_base, LN_base, NID_baseOBJ_base定义。

objects.h 同样提供了c语言类型SN_base, LN_base, NID_baseOBJ_base定义,在obj_mac.h 更新之后,必须对对应的objects.h 中的内容作出同步,及保持与obj_mac.h的定义一至,同时objects.h中也声明了一些对OBJ_name的操作函数。

objects.h 经过perl程序perl obj_dat.pl objects.h obj_dat.h处理之后,生成obj_dat.h头文件。

 

我们可以通过在objects.txt中的注册算法OID,就可以使用命令perl objects.pl objects.txt obj_mac.num obj_mac.h来生成自定义算法的一系列声明.

以下是我们添加的算法

在其中添加一行条目

rsadsi 3 255    : SSF33     : ssf33

分别生成以下声明

obj_dat.h:780:0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x81,0x7F,/* [5001] OBJ_ssf33 */

obj_dat.h:1949:{"SSF33","ssf33",NID_ssf33,9,&(lvalues[5001]),0},

obj_dat.h:3418:&(nid_objs[751]),/* "ssf33" */

obj_dat.h:3958:&(nid_objs[751]),/* OBJ_ssf33                        1 2 840 113549 3 255 */

objects.txt:1046:rsadsi 3 255   : SSF33         : ssf33

obj_mac.h:3294:#define SN_ssf33         "SSF33"

obj_mac.h:3295:#define LN_ssf33         "ssf33"

obj_mac.h:3296:#define NID_ssf33                751

obj_mac.h:3297:#define OBJ_ssf33                OBJ_rsadsi,3L,255L

obj_mac.num:751:ssf33           751

 

2.密码算法接口的定义

typedef struct evp_cipher_st EVP_CIPHER;

/* 加密算法后被names_lh来管理,可以通算法的名称或别名来检索 */

struct evp_cipher_st

       {

       int nid;                         /*加密算法的nid*/

       int block_size;               /*数据块的大小 */

       int key_len;            /* Default value for variable length ciphers */

       int iv_len;              /* 对于CBC,CFB,OFB的加密算法初始化矢量*/

       unsigned long flags;       /* Various flags */

       int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,

                  const unsigned char *iv, int enc);  /* init key */

       int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,

                      const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */

       int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */

       int ctx_size;           /* how big the ctx needs to be */

       int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */

        int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */

       int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */

       void *app_data;             /* Application data */

       };

 

如果正确定义了EVP_CIPHER变量,这个算法就可以被OpenSSL所接受了。

 

下面的宏将定义ECB,CBC,CFB,OFB算法EVP_CIPHER定义。

#define BLOCK_CIPHER_defs(cname, kstruct, /

                            nid, block_size, key_len, iv_len, flags,/

                             init_key, cleanup, set_asn1, get_asn1, ctrl)/

static EVP_CIPHER cname##_cbc = {/

       nid##_cbc, block_size, key_len, iv_len, /

       flags | EVP_CIPH_CBC_MODE,/

       init_key,/

       cname##_cbc_cipher,/

       cleanup,/

       sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+/

              sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),/

       set_asn1, get_asn1,/

       ctrl, /

       NULL /

};/

 

EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }/

static EVP_CIPHER cname##_cfb = {/

       nid##_cfb64, 1, key_len, iv_len, /

       flags | EVP_CIPH_CFB_MODE,/

       init_key,/

       cname##_cfb_cipher,/

       cleanup,/

       sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+/

              sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),/

       set_asn1, get_asn1,/

       ctrl,/

       NULL /

};/

EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }/

static EVP_CIPHER cname##_ofb = {/

       nid##_ofb64, 1, key_len, iv_len, /

       flags | EVP_CIPH_OFB_MODE,/

       init_key,/

       cname##_ofb_cipher,/

       cleanup,/

       sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+/

              sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),/

       set_asn1, get_asn1,/

       ctrl,/

       NULL /

};/

 

EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }/

static EVP_CIPHER cname##_ecb = {/

       nid##_ecb, block_size, key_len, iv_len, /

       flags | EVP_CIPH_ECB_MODE,/

       init_key,/

       cname##_ecb_cipher,/

       cleanup,/

       sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+/

              sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),/

       ctx_size 其中有联合的结构,如何获取EVP_CIPHER_CTX数据长度)

       set_asn1, get_asn1,/

       ctrl,/

       NULL /

};/

 

EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }

上面的宏在经过处理之后,变成了四中加密模式的EVP_CIPHER定义,这个结构中封装了加密操作汉书,密钥初始化函数,以及密钥的清理函数。除了实现加密算法之外,还比需实现对应的密钥结构!

 

EVP_CIPHER_CTX就是密钥结构,完成对加密算法密钥的管理。

typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;

struct evp_cipher_ctx_st

{

       const EVP_CIPHER *cipher;

       int encrypt;            /* encrypt or decrypt */

       int buf_len;            /* number we have left */

 

       unsigned char  oiv[EVP_MAX_IV_LENGTH];   /* original iv */

       unsigned char  iv[EVP_MAX_IV_LENGTH];     /* working iv */

       unsigned char buf[EVP_MAX_IV_LENGTH];     /* saved partial block */

       int num;                       /* used by cfb/ofb mode */

 

       void *app_data;             /* application stuff */

       int key_len;            /* May change for variable length cipher */

/* 通过联合的方式管理密钥,对各种密钥实现灵活的管理 */

       union      {

#ifndef NO_RC4

              struct

                     {

                     unsigned char key[EVP_RC4_KEY_SIZE];

                     RC4_KEY ks;  /* working key */

                     } rc4;

#endif

#ifndef NO_DES

              des_key_schedule des_ks;/* key schedule */

              struct

                     {

                     des_key_schedule ks;/* key schedule */

                     des_cblock inw;

                     des_cblock outw;

                     } desx_cbc;

              struct

                     {

                     des_key_schedule ks1;/* key schedule */

                     des_key_schedule ks2;/* key schedule (for ede) */

                     des_key_schedule ks3;/* key schedule (for ede3) */

                     } des_ede;

#endif

#ifndef NO_IDEA

              IDEA_KEY_SCHEDULE idea_ks;/* key schedule */

#endif

#ifndef NO_RC2

              struct {

                     int key_bits;    /* effective key bits */

                     RC2_KEY ks;/* key schedule */

              } rc2;

#endif

#ifndef NO_RC5

              struct {

                     int rounds;      /* number of rounds */

                     RC5_32_KEY ks;/* key schedule */

              } rc5;

#endif

#ifndef NO_BF

              BF_KEY bf_ks;/* key schedule */

#endif

#ifndef NO_CAST

              CAST_KEY cast_ks;/* key schedule */

#endif

              } c;

};

 

3.示例

熟悉了这些结构,我们就可以通过这些ssf33的算法的申明添加自定义算法了,这里我们以RC4算法为模板只是修改名字来创建我们的算法.

crypto/evp/下添加e_ssf33.c,内容如下

#include <stdio.h>

#include "cryptlib.h"

 

#ifndef OPENSSL_NO_RC4

 

#include <openssl/evp.h>

#include <openssl/objects.h>

#include <openssl/rc4.h>

 

/* FIXME: surely this is available elsewhere? */

#define EVP_SSF33_KEY_SIZE      16

 

typedef struct

    {

    RC4_KEY ks; /* working key */

    } EVP_SSF33_KEY;

 

#define data(ctx) ((EVP_SSF33_KEY *)(ctx)->cipher_data)

 

static int ssf33_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,

            const unsigned char *iv,int enc);

static int ssf33_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,

              const unsigned char *in, unsigned int inl);

static const EVP_CIPHER ssf33_evp_cipher=

    {

    NID_ssf33,

    1,EVP_SSF33_KEY_SIZE,0,

    EVP_CIPH_VARIABLE_LENGTH,

    ssf33_init_key,

    ssf33_cipher,

    NULL,

    sizeof(EVP_SSF33_KEY),

    NULL,

    NULL,

    NULL,

    NULL

    };

const EVP_CIPHER *EVP_ssf33(void)

    {

    return(&ssf33_evp_cipher);

    }

 

static int ssf33_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,

            const unsigned char *iv, int enc)

    {

    RC4_set_key(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),

            key);

    return 1;

    }

 

static int ssf33_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,

              const unsigned char *in, unsigned int inl)

    {

    RC4(&data(ctx)->ks,inl,in,out);

    return 1;

    }

#endif

接下来在evp.h中添加对算法的声明

evp.h:const EVP_CIPHER *EVP_ssf33(void);

这样我们只要在c_allc.c文件中修改OpenSSL_add_all_ciphers函数,使用EVP_add_cipher注册加密函数就可以了.

EVP_add_cipher(EVP_ssf33());

就可以使用此函数了!可以通过evp_test测试实例!^_^

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在OpenSSL中添加自定义加密算法 的相关文章

  • 我想向我的销售点的用户授予特权,但我不知道如何做,有什么建议吗?

    我有一个问题 我有一个用netBeans制作的销售点系统 2个用户可以在我的系统中注册 管理员 和 供应商 系统中有几个模块 包括 Inventario 模块允许您在数据库中输入 修改 删除和搜索文章 问题是我希望只有管理员有权限进入该模块
  • Objective-C 有没有办法捕获发送到 nil 的消息?

    我刚刚被一种烦人的东西咬了bug https stackoverflow com questions 913627 uiviewcontroller viewdidload not being calledObjective C 中的 向
  • C 中的 NULL 是否需要/定义为零?

    在我的 GCC 测试程序中 NULL 似乎为零 但维基百科说NULL只需要指向不可寻址的内存 有编译器做吗NULL非零 我很好奇是否if ptr NULL 是比更好的练习if ptr NULL is guaranteed to be zer
  • C# Null 传播运算符/条件访问表达式和 if 块

    The 空传播运算符 条件访问表达式 https roslyn codeplex com discussions 540883进来c 6 0 questions tagged c 23 6 0看起来是一个非常方便的功能 但我很好奇它是否有助
  • 块执行后变量返回 null

    我正在调度一个队列来在单独的线程上下载一些 flickr 照片 在 viewWillAppear 中 当我记录块内数组的内容时 它完美地显示了所有内容 dispatch queue t photoDowonload dispatch que
  • 如何在Ireport中给出多选参数空值的条件?

    我正在使用以下方法编写报告iReport http en wikipedia org wiki JasperReports Third party tools我想在其中添加空值条件 它使用单选选项 city P p city or P p
  • SQL Server 不使用索引将日期时间与非空进行比较

    我有一个与其他任何表都不相关的简单表 它有一个非 PK 列 它是一个日期 我已经为该列创建了一个非聚集索引 如果我提出这个查询 select from table where datecolumn is not null 但如果我删除 no
  • 如何在c中的某个位置终止字符指针?

    我试图通过设置空终止符来终止 c 中的字符指针 在特定位置 例如 如果我有一个 char 指针 char hi hello 我希望它是 hell 通过设置o为空 我尝试过使用 strcpy 来执行此操作 例如 strcpy hi 4 0 但
  • Google BigQuery,使用“unnest”函数时丢失了空行

    StandardSQL WITH tableA AS SELECT T001 T002 T003 AS T id 1 5 AS L id UNION ALL SELECT T008 T009 AS T id NULL AS L id SEL
  • 通过 NULL 指针访问类成员

    我正在尝试 C 发现下面的代码非常奇怪 class Foo public virtual void say virtual hi std cout lt lt Virtual Hi void say hi std cout lt lt Hi
  • 为什么C++中没有“NULL引用”?

    我正在阅读 C 常见问题解答 8 6 什么时候应该使用引用 什么时候应该使用指针 http www parashift com c faq lite refs vs ptrs html 特别是以下声明 可以时使用引用 必要时使用指针 上述情
  • 堆分配对象是否有一个永不为空的唯一所有者?

    目前 我正在存储一个集合std unique ptrs 到堆分配的多态类型对象 struct Foo virtual Foo default Collection
  • 如何从 f# 返回一个空元组到 c#? [复制]

    这个问题在这里已经有答案了 我有这个类型正确的 C 函数 static System Tuple
  • DBNull 怎么会不等于 DBNull

    我有以下代码行 if DBNull Value Equals o o null where o is object o in row ItemArray我不断收到错误 gt Xml type List of xdt untypedAtomi
  • Java 空值检查

    我有一个thread1 if object null object play 和另一个thread2可以写null into object随时参考 我将同时运行这些线程 我知道thread2可以重写object后参考null检查并会抛出Nu
  • 淹没在空无的海洋中

    我继承的一个应用程序跟踪对材料样品执行的实验室测试结果 数据存储在单个表 tblSampleData 中 其主键为 SampleID 并有 235 列代表潜在的测试结果 问题是每个样本仅执行少量测试 因此每行包含超过 200 个空值 实际上
  • 空字符串与NULL

    我有一个表 其中一些行有一些空白cells 我尝试使用 IS NULL 函数选择此类行 但查询选择了 0 行 select from zzz fkp registration female where fname is null 0 row
  • 删除指针后将其设为 NULL 是一个好习惯吗?

    我首先要说的是 使用智能指针 您将永远不必担心这个问题 下面的代码有什么问题 Foo p new Foo use p delete p p NULL 这是由答案和评论 https stackoverflow com questions 19
  • 查询外键列可以为NULL的地方

    我想获取数据 如果orgid 2或者如果根本没有行uid orgid is an integer 我能想到的最接近的事情就是做IS NULL但我没有得到数据uid没有一个orgid排 任何想法 select u uid u fname u
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast

随机推荐

  • Edge浏览器以图搜图插件Search by Image安装与使用

    1 安装插件 2 以图搜图 右键 gt Search by Image gt Yandex 3 成功搜图 4 如果Yandex打不开 看这个文章 Windows系统无法访问 yandex com 解决方案
  • springboot调整请求头大小_解决Springboot get请求是参数过长的情况

    问题原因 Springboot get请求是参数过长抛出异常 Request header is too large 的问题 错误描述 java lang IllegalArgumentException Request header is
  • python3.8+pytorch 1.7.0+cuda10.2+cuDNN

    本文是在电脑中直接安装cuda10 2的过程 如果是要在anaconda环境中安装的话 可以直接只在虚拟环境中使用命令进行安装 用以下链接中的过程即可 在anaconda虚拟环境中安装pytorch和cuda教程 安装过程中看到的不错的教程
  • CVE-2022-30190复现及原理

    今天各厂商都在发布CVE 2022 30190的安全通告 作为一个与Office有关的RCE漏洞 其原理并不复杂 但利用非常简单无脑甚至不用点击 以后钓鱼肯定要经常用 这里简单复现分析下 环境 Win10 0 16299 32位 Micro
  • OLED透明屏原彩优势和特点解析:开创显示技术新时代

    OLED透明屏 原彩作为一项领先的显示技术 正以其卓越的性能和创新的设计特点引起广泛关注 本文将通过深入探讨OLED透明屏 原彩的优势和特点 应用领域 技术发展以及未来前景等方面内容 并结合具体数据 报告和行业动态 为读者提供专业可信的信息
  • java设置httpheaders_HttpClient 请求添加Header头部信息

    HTTP消息可以包含许多描述消息属性的标头 例如内容长度 内容类型 授权等 HttpClient提供了检索 添加 删除和枚举标头的方法 在下面的教程中 我们将演示如何将自定义HTTP头添加到HttpClient和Http请求方法 Maven
  • 蓬莱小课:统计学中18种数据分析方法汇总

    Part1描述统计 描述统计是通过图表或数学方法 对数据资料进行整理 分析 并对数据的分布状态 数字特征和随机变量之间关系进行估计和描述的方法 描述统计分为集中趋势分析和离中趋势分析和相关分析三大部分 集中趋势分析 集中趋势分析主要靠平均数
  • 【Pytorch】第 5 章 :解决多臂老虎机问题

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 【C++】this指针的理解和__thiscall的调用方式

    我们可以从以下三方面来认识this指针 一 为什么会产生this指针 二 this指针的特点 三 thiscall的调用方式 四 问题 一 为什么会产生this指针 class Box public int volume int heigh
  • es guass 案例

    analyze analyzer standard curl XPOST http 192 168 1 47 9200 searchtube search analyzer ik max word analyzer ik max word
  • 国内常见pip使用镜像源地址

    清华大学镜像源 https pypi tuna tsinghua edu cn simple 阿里云镜像源 http mirrors aliyun com pypi simple 中国科技大学镜像源 https pypi mirrors u
  • vmware 共享文件夹hgfs没有显示

    挂载共享文件夹 当完成共享文件夹之后 会出现在 mnt hgfs目录下 如果没有hgfs文件夹则创建 然后进入虚拟机挂载文件夹 然后执行sudo vmhgfs fuse host mnt hgfs 但是有时候并不显示共享的文件夹 但是如果使
  • c++11之数组array

    c 11数组 定义 注意事项 例子 STL array vector list比较 定义 C 11后 标准库引入了更现代化的数组std array cppreference com是这样介绍的 定义于头文件 template lt clas
  • Windows下如何查看被占用进程及结束进程?

    Windows下如何查看被占用进程及结束进程 查找所有运行的端口命令 netstat ano 查找被占用端口对应的PID netstat aon findstr 2990 查找指定PID的进程 tasklist findstr 1004 结
  • C++学习(十六)有关dump的理解

    1 作为动词 转存的意思 将内容从一个位置转存到另一个位置 2 作为名词 转存文件的意思 某些程序生成的文件 比如操作系统生成的调试日志文件
  • Action 无参数委托详解

    C 委托Action Action
  • opencv实战——机器视觉检测和计数

    引言 在机器视觉中 有时需要对产品进行检测和计数 其难点无非是对于产品的图像分割 由于之前网购的维生素片 有时候忘了今天有没有吃过 就想对瓶子里的药片计数 在学习opencv以后 希望实现对于维生素片分割计数算法 本次实战在基于形态学的基础
  • 跳转关键字

    跳转关键字 break continue break 不能单独存在的 可以用在switch和循环中 表示结束 跳出的意思 代码示例 1 吃1 5号包子 for int i 1 i lt 5 i System out println 在吃第
  • 【C++】深入模板

    文章目录 1 反向迭代器的优化 1 1优化目标 1 2优化 1 3typename的其他使用方式 1 4适合所有容器的打印函数 2 非类型模板参数 3 函数模板特化 4 类模板特化 4 1全特化 4 2偏特化 4 2 1部分模板参数类型特化
  • 在OpenSSL中添加自定义加密算法

    在OpenSSL中添加自定义加密算法 1 加密算法的加载 1 2 密码算法接口的定义 4 3 示例 8 1 加密算法的加载 在调用加密算法之前 通过调用OpenSSL add all algorithms来加载加密算法函数和单向散列算法函数