.NET Core加解密实战系列之——RSA非对称加密算法

简介

加解密现状,编写此项目的背景:

  • 需要考虑系统环境兼容性问题(Linux、Windows)

  • 语言互通问题(如C#、Java)

  • 网上资料版本不一、不全面

  • .NET官方库密码算法提供不全面,很难针对其他语言(Java)进行适配

本系列文章主要介绍如何结合BouncyCastle在 .NET Core 中使用非对称加密算法、编码算法、哈希算法、对称加密算法、国密算法等一系列算法,内容篇幅代码居多(加解密算法相关的原理知识网上有很多,因此不过多介绍)。如有错误之处,还请大家批评指正。

本系列代码项目地址:https://github.com/fuluteam/ICH.BouncyCastle.git

功能依赖

BouncyCastle(https://www.bouncycastle.org/csharp) 是一个开放源码的轻量级密码术包;它支持大量的密码术算法,它提供了很多.NET Core标准库没有的算法。

支持.NET 4,.NET Standard 1.0-2.0,WP,Silverlight,MonoAndroid,Xamarin.iOS,.NET Core

功能依赖
Portable.BouncyCastlePortable.BouncyCastle • 1.8.5

生成RSA秘钥

PKCS1格式

/// <summary>/// PKCS1(非Java适用)/// </summary>/// <param name="keySize">密钥长度”一般只是指模值的位长度。目前主流可选值:1024、2048、3072、4096...</param>/// <param name="format">PEM格式</param>/// <returns></returns>public RSAKeyParameter Pkcs1(int keySize, bool format=false){var keyGenerator = GeneratorUtilities.GetKeyPairGenerator("RSA");keyGenerator.Init(new KeyGenerationParameters(new SecureRandom(), keySize));var keyPair = keyGenerator.GenerateKeyPair();var subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);if (!format){return new RSAKeyParameter{PrivateKey = Base64.ToBase64String(privateKeyInfo.ParsePrivateKey().GetEncoded()),PublicKey = Base64.ToBase64String(subjectPublicKeyInfo.GetEncoded())};}var rsaKey = new RSAKeyParameter();using (var sw = new StringWriter()){var pWrt = new PemWriter(sw);pWrt.WriteObject(keyPair.Private);pWrt.Writer.Close();rsaKey.PrivateKey = sw.ToString();}using (var sw = new StringWriter()){var pWrt = new PemWriter(sw);pWrt.WriteObject(keyPair.Public);pWrt.Writer.Close();rsaKey.PublicKey = sw.ToString();}return rsaKey;}

PKCS8格式

/// <summary>/// PKCS8(JAVA适用)/// </summary>/// <param name="keySize">密钥长度”一般只是指模值的位长度。目前主流可选值:1024、2048、3072、4096...</param>/// <param name="format">PEM格式</param>/// <returns></returns>public RSAKeyParameter Pkcs8(int keySize, bool format=false){var keyGenerator = GeneratorUtilities.GetKeyPairGenerator("RSA");keyGenerator.Init(new KeyGenerationParameters(new SecureRandom(), keySize));var keyPair = keyGenerator.GenerateKeyPair();var subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);if (!format){return new RSAKeyParameter{PrivateKey = Base64.ToBase64String(privateKeyInfo.GetEncoded()),PublicKey = Base64.ToBase64String(subjectPublicKeyInfo.GetEncoded())};}var rsaKey = new RSAKeyParameter();using (var sw = new StringWriter()){var pWrt = new PemWriter(sw);var pkcs8 = new Pkcs8Generator(keyPair.Private);pWrt.WriteObject(pkcs8);pWrt.Writer.Close();rsaKey.PrivateKey = sw.ToString();}using (var sw = new StringWriter()){var pWrt = new PemWriter(sw);pWrt.WriteObject(keyPair.Public);pWrt.Writer.Close();rsaKey.PublicKey = sw.ToString();}return rsaKey;}

私钥操作

PKCS1与PKCS8格式互转

仅私钥有PKCS1和PKCS8之分,公钥无格式区别。

/// <summary>/// Pkcs1>>Pkcs8/// </summary>/// <param name="privateKey">Pkcs1私钥</param>/// <param name="format">是否转PEM格式</param>/// <returns></returns>public static string PrivateKeyPkcs1ToPkcs8(string privateKey, bool format = false){var akp = RSAUtilities.GetAsymmetricKeyParameterFormPrivateKey(privateKey);if (format){var sw = new StringWriter();var pWrt = new PemWriter(sw);var pkcs8 = new Pkcs8Generator(akp);pWrt.WriteObject(pkcs8);pWrt.Writer.Close();return sw.ToString();}else{var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(akp);return Base64.ToBase64String(privateKeyInfo.GetEncoded());}}
/// <summary>/// Pkcs8>>Pkcs1/// </summary>/// <param name="privateKey">Pkcs8私钥</param>/// <param name="format">是否转PEM格式</param>/// <returns></returns>public static string PrivateKeyPkcs8ToPkcs1(string privateKey, bool format = false){var akp = RSAUtilities.GetAsymmetricKeyParameterFormAsn1PrivateKey(privateKey);if (format){var sw = new StringWriter();var pWrt = new PemWriter(sw);pWrt.WriteObject(akp);pWrt.Writer.Close();return sw.ToString();}else{var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(akp);return Base64.ToBase64String(privateKeyInfo.ParsePrivateKey().GetEncoded());}}

PKCS1与PKCS8私钥中提取公钥

/// <summary>/// 从Pkcs1私钥中提取公钥/// </summary>/// <param name="privateKey">Pkcs1私钥</param>/// <returns></returns>public static string GetPublicKeyFromPrivateKeyPkcs1(string privateKey){var instance = RsaPrivateKeyStructure.GetInstance(Base64.Decode(privateKey));var publicParameter = (AsymmetricKeyParameter)new RsaKeyParameters(false, instance.Modulus,instance.PublicExponent);var privateParameter = (AsymmetricKeyParameter)new RsaPrivateCrtKeyParameters(instance.Modulus,instance.PublicExponent, instance.PrivateExponent, instance.Prime1, instance.Prime2, instance.Exponent1,instance.Exponent2, instance.Coefficient);var keyPair = new AsymmetricCipherKeyPair(publicParameter, privateParameter);var subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);return Base64.ToBase64String(subjectPublicKeyInfo.GetEncoded());}
/// <summary>/// 从Pkcs8私钥中提取公钥/// </summary>/// <param name="privateKey">Pkcs8私钥</param>/// <returns></returns>public static string GetPublicKeyFromPrivateKeyPkcs8(string privateKey){var privateKeyInfo = PrivateKeyInfo.GetInstance(Asn1Object.FromByteArray(Base64.Decode(privateKey)));privateKey = Base64.ToBase64String(privateKeyInfo.ParsePrivateKey().GetEncoded());var instance = RsaPrivateKeyStructure.GetInstance(Base64.Decode(privateKey));var publicParameter = (AsymmetricKeyParameter)new RsaKeyParameters(false, instance.Modulus,instance.PublicExponent);var privateParameter = (AsymmetricKeyParameter)new RsaPrivateCrtKeyParameters(instance.Modulus,instance.PublicExponent, instance.PrivateExponent, instance.Prime1, instance.Prime2, instance.Exponent1,instance.Exponent2, instance.Coefficient);var keyPair = new AsymmetricCipherKeyPair(publicParameter, privateParameter);var subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);return Base64.ToBase64String(subjectPublicKeyInfo.GetEncoded());}

PEM操作

PEM格式密钥读取

public static string ReadPkcs1PrivateKey(string text){if (!text.StartsWith("-----BEGIN RSA PRIVATE KEY-----")){return text;}using (var reader = new StringReader(text)){var pr = new PemReader(reader);var keyPair = pr.ReadObject() as AsymmetricCipherKeyPair;pr.Reader.Close();var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair?.Private);return Base64.ToBase64String(privateKeyInfo.ParsePrivateKey().GetEncoded());}}public static string ReadPkcs8PrivateKey(string text){if (!text.StartsWith("-----BEGIN PRIVATE KEY-----")){return text;}using (var reader = new StringReader(text)){var pr = new PemReader(reader);var akp = pr.ReadObject() as AsymmetricKeyParameter; ;pr.Reader.Close();return Base64.ToBase64String(PrivateKeyInfoFactory.CreatePrivateKeyInfo(akp).GetEncoded());}}public static string ReadPublicKey(string text){if (!text.StartsWith("-----BEGIN PUBLIC KEY-----")){return text;}using (var reader = new StringReader(text)){var pr = new PemReader(reader);var keyPair = pr.ReadObject() as AsymmetricCipherKeyPair;pr.Reader.Close();var subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair?.Public);returnBase64.ToBase64String(subjectPublicKeyIno.GetEncoded());}}

PEM格式密钥写入

public static string WritePkcs1PrivateKey(string privateKey){if (privateKey.StartsWith("-----BEGIN RSA PRIVATE KEY-----")){return privateKey;}var akp = RSAUtilities.GetAsymmetricKeyParameterFormPrivateKey(privateKey);using (var sw = new StringWriter()){var pWrt = new PemWriter(sw);pWrt.WriteObject(akp);pWrt.Writer.Close();return sw.ToString();}}public static string WritePkcs8PrivateKey(string privateKey){if (privateKey.StartsWith("-----BEGIN PRIVATE KEY-----")){return privateKey;}var akp = RSAUtilities.GetAsymmetricKeyParameterFormAsn1PrivateKey(privateKey);using (var sw = new StringWriter()){var pWrt = new PemWriter(sw);var pkcs8 = new Pkcs8Generator(akp);pWrt.WriteObject(pkcs8);pWrt.Writer.Close();return sw.ToString();}}public static string WritePublicKey(string publicKey){if (publicKey.StartsWith("-----BEGIN PUBLIC KEY-----")){return publicKey;}var akp = RSAUtilities.GetAsymmetricKeyParameterFormPublicKey(publicKey);using (var sw = new StringWriter()){var pWrt = new PemWriter(sw);pWrt.WriteObject(akp);pWrt.Writer.Close();return sw.ToString();}}

RSA加解密

获取非对称秘钥参数(AsymmetricKeyParameter)

/// <summary>/// -----BEGIN RSA PRIVATE KEY-----/// .../// -----END RSA PRIVATE KEY-----/// </summary>/// <param name="privateKey">Pkcs1格式私钥</param>/// <returns></returns>public static AsymmetricKeyParameter GetAsymmetricKeyParameterFormPrivateKey(string privateKey){if (string.IsNullOrEmpty(privateKey)){throw new ArgumentNullException(nameof(privateKey));}var instance = RsaPrivateKeyStructure.GetInstance(Base64.Decode(privateKey));return new RsaPrivateCrtKeyParameters(instance.Modulus, instance.PublicExponent, instance.PrivateExponent,instance.Prime1, instance.Prime2, instance.Exponent1, instance.Exponent2, instance.Coefficient);}/// <summary>/// -----BEGIN PRIVATE KEY-----/// .../// -----END PRIVATE KEY-----/// </summary>/// <param name="privateKey">Pkcs8格式私钥</param>/// <returns></returns>public static AsymmetricKeyParameter GetAsymmetricKeyParameterFormAsn1PrivateKey(string privateKey){return PrivateKeyFactory.CreateKey(Base64.Decode(privateKey));}/// <summary>/// -----BEGIN PUBLIC KEY-----/// .../// -----END PUBLIC KEY-----/// </summary>/// <param name="publicKey">公钥</param>/// <returns></returns>public static AsymmetricKeyParameter GetAsymmetricKeyParameterFormPublicKey(string publicKey){if (string.IsNullOrEmpty(publicKey)){throw new ArgumentNullException(nameof(publicKey));}return PublicKeyFactory.CreateKey(Base64.Decode(publicKey));}

RSA加解与解密

/// <summary>/// RSA加密/// </summary>/// <param name="data">未加密数据字节数组</param>/// <param name="parameters">非对称密钥参数</param>/// <param name="algorithm">密文算法</param>/// <returns>已加密数据字节数组</returns>public static byte[] Encrypt(byte[] data, AsymmetricKeyParameter parameters, string algorithm){if (data == null){throw new ArgumentNullException(nameof(data));}if (parameters == null){throw new ArgumentNullException(nameof(parameters));}if (string.IsNullOrEmpty(algorithm)){throw new ArgumentNullException(nameof(algorithm));}var bufferedCipher = CipherUtilities.GetCipher(algorithm);bufferedCipher.Init(true, parameters);return bufferedCipher.DoFinal(data);}/// <summary>/// RSA解密/// </summary>/// <param name="data">已加密数据字节数组</param>/// <param name="parameters">非对称密钥参数</param>/// <param name="algorithm">密文算法</param>/// <returns>未加密数据字节数组</returns>public static byte[] Decrypt(byte[] data, AsymmetricKeyParameter parameters, string algorithm){if (data == null){throw new ArgumentNullException(nameof(data));}if (parameters == null){throw new ArgumentNullException(nameof(parameters));}if (string.IsNullOrEmpty(algorithm)){throw new ArgumentNullException(nameof(algorithm));}var bufferedCipher = CipherUtilities.GetCipher(algorithm);bufferedCipher.Init(false, parameters);return bufferedCipher.DoFinal(data);}/// <summary>/// RSA加密——Base64/// </summary>/// <param name="data">未加密字符串</param>/// <param name="parameters">非对称密钥参数</param>/// <param name="algorithm">密文算法</param>/// <returns>已加密Base64字符串</returns>public static string EncryptToBase64(string data, AsymmetricKeyParameter parameters, string algorithm){return Base64.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(data), parameters, algorithm));}/// <summary>/// RSA解密——Base64/// </summary>/// <param name="data">已加密Base64字符串</param>/// <param name="parameters">非对称密钥参数</param>/// <param name="algorithm">密文算法</param>/// <returns>未加密字符串</returns>public static string DecryptFromBase64(string data, AsymmetricKeyParameter parameters, string algorithm){return Encoding.UTF8.GetString(Decrypt(Base64.Decode(data), parameters, algorithm));}/// <summary>/// RSA加密——十六进制/// </summary>/// <param name="data">未加密字符串</param>/// <param name="parameters">非对称密钥参数</param>/// <param name="algorithm">密文算法</param>/// <returns>已加密十六进制字符串</returns>public static string EncryptToHex(string data, AsymmetricKeyParameter parameters, string algorithm){return Hex.ToHexString(Encrypt(Encoding.UTF8.GetBytes(data), parameters, algorithm));}///  <summary>/// RSA解密——十六进制/// </summary>/// <param name="data">已加密十六进制字符串</param>/// <param name="parameters">非对称密钥参数</param>/// <param name="algorithm">密文算法</param>/// <returns>未加密字符串</returns>public static string DecryptFromHex(string data, AsymmetricKeyParameter parameters, string algorithm){return Encoding.UTF8.GetString(Decrypt(Hex.Decode(data), parameters, algorithm));}

RSA密文算法

public const string RSA_NONE_NoPadding = "RSA/NONE/NoPadding";public const string RSA_NONE_PKCS1Padding = "RSA/NONE/PKCS1Padding";public const string RSA_NONE_OAEPPadding = "RSA/NONE/OAEPPadding";public const string RSA_NONE_OAEPWithSHA1AndMGF1Padding = "RSA/NONE/OAEPWithSHA1AndMGF1Padding";public const string RSA_NONE_OAEPWithSHA224AndMGF1Padding = "RSA/NONE/OAEPWithSHA224AndMGF1Padding";public const string RSA_NONE_OAEPWithSHA256AndMGF1Padding = "RSA/NONE/OAEPWithSHA256AndMGF1Padding";public const string RSA_NONE_OAEPWithSHA384AndMGF1Padding = "RSA/NONE/OAEPWithSHA384AndMGF1Padding";public const string RSA_NONE_OAEPWithMD5AndMGF1Padding = "RSA/NONE/OAEPWithMD5AndMGF1Padding";public const string RSA_ECB_NoPadding = "RSA/ECB/NoPadding";public const string RSA_ECB_PKCS1Padding = "RSA/ECB/PKCS1Padding";public const string RSA_ECB_OAEPPadding = "RSA/ECB/OAEPPadding";public const string RSA_ECB_OAEPWithSHA1AndMGF1Padding = "RSA/ECB/OAEPWithSHA1AndMGF1Padding";public const string RSA_ECB_OAEPWithSHA224AndMGF1Padding = "RSA/ECB/OAEPWithSHA224AndMGF1Padding";public const string RSA_ECB_OAEPWithSHA256AndMGF1Padding = "RSA/ECB/OAEPWithSHA256AndMGF1Padding";public const string RSA_ECB_OAEPWithSHA384AndMGF1Padding = "RSA/ECB/OAEPWithSHA384AndMGF1Padding";public const string RSA_ECB_OAEPWithMD5AndMGF1Padding = "RSA/ECB/OAEPWithMD5AndMGF1Padding";......

编码算法

大家要明白,不管是对称算法还是非对称算法,其输入与输出均是字节数组,通常我们要结合编码算法对加密之后或解密之前的数据,进行编码操作。

BouncyCastle提供的Base64编码算法

namespace Org.BouncyCastle.Utilities.Encoders{public sealed class Base64{//public static byte[] Decode(byte[] data);//public static byte[] Decode(string data);//public static int Decode(string data, Stream outStream);//public static byte[] Encode(byte[] data);//public static byte[] Encode(byte[] data, int off, int length);//public static int Encode(byte[] data, Stream outStream);//public static int Encode(byte[] data, int off, int length, Stream outStream);public static string ToBase64String(byte[] data);public static string ToBase64String(byte[] data, int off, int length);}}

BouncyCastle提供的Hex十六进制编码算法

namespace Org.BouncyCastle.Utilities.Encoders{//// 摘要://     Class to decode and encode Hex.public sealed class Hex{//public static byte[] Decode(byte[] data);//public static byte[] Decode(string data);//public static int Decode(string data, Stream outStream);//public static byte[] Encode(byte[] data);//public static byte[] Encode(byte[] data, int off, int length);//public static int Encode(byte[] data, Stream outStream);//public static int Encode(byte[] data, int off, int length, Stream outStream);public static string ToHexString(byte[] data);public static string ToHexString(byte[] data, int off, int length);}}

RSA加解密示例

private static void RSA_ECB_PKCS1Padding(){var data = "hello rsa";Console.WriteLine($"加密原文:{data}");// rsa pkcs8 private key encrypt//algorithm  rsa/ecb/pkcs1paddingvar pkcs8data = RSA.EncryptToBase64(data, RSAUtilities.GetAsymmetricKeyParameterFormAsn1PrivateKey(pkcs8_1024_private_key),CipherAlgorithms.RSA_ECB_PKCS1Padding);Console.WriteLine("密钥格式:pkcs8,密文算法:rsa/ecb/pkcs1padding,加密结果");Console.WriteLine(pkcs8data);//rsa pkcs1 private key encrypt//algorithm  rsa/ecb/pkcs1paddingvar pkcs1data = RSA.EncryptToBase64(data, RSAUtilities.GetAsymmetricKeyParameterFormPrivateKey(pkcs1_1024_private_key),CipherAlgorithms.RSA_ECB_PKCS1Padding);Console.WriteLine($"密钥格式:pkcs1,密文算法:rsa/ecb/pkcs1padding");Console.WriteLine(pkcs1data);Console.WriteLine($"加密结果比对是否一致:{pkcs8data.Equals(pkcs1data)}");var _1024_public_key = RSAKeyConverter.GetPublicKeyFromPrivateKeyPkcs1(pkcs1_1024_private_key);Console.WriteLine($"从pkcs1私钥中提取公钥:");Console.WriteLine(_1024_public_key);Console.WriteLine("使用公钥解密数据:");//rsa public key decrypt//algorithm  rsa/ecb/pkcs1paddingConsole.WriteLine(RSA.DecryptFromBase64(pkcs1data, RSAUtilities.GetAsymmetricKeyParameterFormPublicKey(_1024_public_key),CipherAlgorithms.RSA_ECB_PKCS1Padding));Console.WriteLine();}

下期预告

下一篇将介绍哈希算法(HMACSHA1、HMACSHA256、SHA1、SHA1WithRSA、SHA256、SHA256WithRSA),敬请期待…

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

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

相关文章

[数据结构-严蔚敏版]P42多项式Polynomial的实现

大家如果发现代码有错误&#xff0c;麻烦评论告知一下!!! 下面的代码多项式相乘的算法实现并不是书上那种&#xff0c;书上那种我实在是看不懂&#xff0c;所以用了自己的方法写了相乘的算法&#xff0c;就是模拟手算过程&#xff0c;一个一个相乘。 代码如下: #include <…

number five

一、外单履行域业务熟悉 申请了各种权限 看了部分三号项目 熟悉测试流程&#xff0c;例如履行的一些工具&#xff0c;只是熟悉了平台&#xff0c;因为部分权限未申请&#xff0c;没有操作过测试。 对于三号项目概念还没成体系&#xff0c;但了解了相关测试任务。 中间件hsf…

.Net Core实战之基于角色的访问控制的设计

前言上个月&#xff0c;我写了两篇微服务的文章&#xff1a;《.Net微服务实战之技术架构分层篇》与《.Net微服务实战之技术选型篇》&#xff0c;微服务系列原有三篇&#xff0c;当我憋第三篇的内容时候一直没有灵感&#xff0c;因此先打算放一放。本篇文章与源码原本打算实在去…

[数据结构-严蔚敏版]P46栈的顺序存储表示

大家如果发现代码有错误&#xff0c;麻烦评论告知一下!!! 代码如下: #include <iostream> using namespace std;const int STACK_INIT_SIZE 100; const int STACKINCREMENT 10;typedef int ElemType;typedef struct {ElemType *base;ElemType *top;int stacksize; }S…

ProcessOn使用

文章目录1. 拥有一个账号;2.思维导图&#xff1a;快速添加主题&#xff1a;移动主题位置和排序用格式刷来复制主题样式善用右键菜单快捷键后续使用时再补充 ^ ^1. 拥有一个账号; 2.思维导图&#xff1a; 快速添加主题&#xff1a; 移动主题位置和排序 用格式刷来复制主题样式…

基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)

系列文章使用 abp cli 搭建项目给项目瘦身&#xff0c;让它跑起来完善与美化&#xff0c;Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API&#xff0c;包装返回模型再说Swagger&#xff0c;分组、描述、小绿锁接入GitHub&#xff0c;用JWT保护你的API异常处理和…

[数据结构-严蔚敏版]P48栈的链式表示

代码如下: #include <iostream> using namespace std;typedef int ElemType;typedef struct SNode {ElemType data;SNode *next; }SNode;typedef struct {SNode *top; }SqStack;bool initStack(SqStack &s) {s.top nullptr;return true; }bool destroyStack(SqStac…

还有多少人不会用K8s?.NET高级高薪岗,开始要求了!

毫无疑问&#xff0c;Kubernetes已经成为容器编排事实标准。除了已经拥抱Kubernetes的Google、BAT、京东、奇虎360等巨头大厂外&#xff0c;更多的企业也都在向Kubernetes迁移。容器技术大势所趋&#xff0c;是互联网企业目前急需的技术人才之一&#xff0c;已成为运维工程师、…

[数据结构-严蔚敏版]P61ADT Queue的表示与实现(单链队列-队列的链式存储结构)

代码如下: #include <iostream> using namespace std;typedef int ElemType;typedef struct QNode {ElemType data;QNode *next; }QNode ,*QueuePtr;typedef struct {QueuePtr front;QueuePtr rear; }LinkQueue;bool initQueue(LinkQueue &q) {q.front q.rear new…

基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)

系列文章使用 abp cli 搭建项目给项目瘦身&#xff0c;让它跑起来完善与美化&#xff0c;Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API&#xff0c;包装返回模型再说Swagger&#xff0c;分组、描述、小绿锁接入GitHub&#xff0c;用JWT保护你的API异常处理和…

[数据结构-严蔚敏版]P64循环队列-队列的顺序存储结构

代码如下: #include <iostream> using namespace std;const int MAXQSIZE 10;typedef int ElemType;typedef struct {ElemType *base;int front;int rear; }SqQueue;bool initQueue(SqQueue &q) {q.base new ElemType[MAXQSIZE];if (!q.base) return false;q.fron…

BeetleX.FastHttpApi之Vuejs扩展

非常喜欢用vuejs,但又不想花时间去搞nodejs和webpack之类的&#xff0c;所以才有了BeetleX.FastHttpApi.VueExtend这样一个组件&#xff1b;组件的主要功能就是可以实现在vs.net中编写*.vue并直接引用到服务中&#xff0c;这样对于我这个习惯在vs.net写服务应的带来极大的方便性…

C++的new、delete需要注意的一点:使用危险函数导致的越界CRT detected that the application wrote to memory after end of heap

new、delete需要注意的一个特性 正常情况new一个数组之后&#xff0c;用delete释放是没有问题的。但是当对new得到的堆区进行越界的写入操作&#xff08;读操作不会&#xff09;将会导致delete时出现段错误&#xff0c;无法进行删除。如下面的程序所示&#xff1a; 数组大小只…

数据结构与算法专题——第四题 字符串相似度

这篇我们看看 最长公共子序列 的另一个版本&#xff0c;求字符串相似度(编辑距离)&#xff0c;我也说过了&#xff0c;这是一个非常实用的算法&#xff0c;在DNA对比&#xff0c;网页聚类等方面都有用武之地。一&#xff1a;概念对于两个字符串 A 和 B&#xff0c;通过基本的增…

[数据结构-严蔚敏版]P71串的抽象数据类型的定义

代码如下: #include <iostream> #include <string> using namespace std;typedef struct {char *ch;int length; }String;bool initString(String &s) {s.ch nullptr;s.length 0;return true; }bool strAssign(String &s, const char *ch) {int len st…

三分钟学会.NET Core Jwt 策略授权认证

一.前言大家好我又回来了&#xff0c;前几天讲过一个关于Jwt的身份验证最简单的案例&#xff0c;但是功能还是不够强大&#xff0c;不适用于真正的项目&#xff0c;是的&#xff0c;在真正面对复杂而又苛刻的客户中&#xff0c;我们会不知所措&#xff0c;就现在需要将认证授权…

[数据结构-严蔚敏版]P65离散事件模拟(银行客户的离散事件驱动模拟程序)

写这个简单玩意&#xff0c;居然花费了我6小时&#xff0c;唉!!!&#xff0c;还是太菜了! 中间已经起了放弃的念头了&#xff0c;最后还是坚持下来了! 总结&#xff1a; (1)漏了p p->next (2)队列删除元素的时候&#xff0c;删除的是最后一个忘记特判。 (3)写的时候太急了…

[温故知新] 编程原则和模式

写了这么多年代码&#xff0c;依旧做不好一个项目做好一个项目是人力、产品、业务、技术、运营的结合&#xff0c;可能还叠加一点时机的因素&#xff0c;就我们码农而言&#xff0c;工作就是搬砖&#xff0c;实现产品&#xff0c; 给业务提供支撑。“给祖传代码加 BUG 修 BUG”…

IntelliJ IDEA中快捷键大全+出现的问题

参照 文章目录1.Ctrl2.Alt3.Shift4.Ctrl Alt5.Ctrl Shift6.Alt Shift7.Ctrl Shift Alt8.其他idea如何将设置包名展开当出现右键&#xff0c;没有创建包选项时idea没有maven图标安装mysql和idea配置idea查看代码的最近修改人及时间1.Ctrl 快捷键介绍Ctrl F在当前文件进行…

基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(八)

系列文章使用 abp cli 搭建项目给项目瘦身&#xff0c;让它跑起来完善与美化&#xff0c;Swagger登场数据访问和代码优先自定义仓储之增删改查统一规范API&#xff0c;包装返回模型再说Swagger&#xff0c;分组、描述、小绿锁接入GitHub&#xff0c;用JWT保护你的API异常处理和…