一款实用的.NET Core加密解密工具类库

前言

在我们日常开发工作中,为了数据安全问题对数据加密、解密是必不可少的。加密方式有很多种如常见的AES,RSA,MD5,SAH1,SAH256,DES等,这时候假如我们有一个封装的对应加密解密工具类可以直接调用,那这样可以节省不少的开发时间。今天推荐一款实用的.NET Core加密解密工具类库:NETCore.Encrypt。

项目介绍

NETCore.Encrypt是.NET Core加密解密工具类库,包括AES、RSA、MD5、SHA1、DES、SHA256、SHA384、SHA512等更多功能。

项目源码

MD5加密

封装方法

        #region MD5
        /// <summary>
        /// MD5 hash
        /// </summary>
        /// <param name="srcString">The string to be encrypted.</param>
        /// <param name="length">The length of hash result , default value is <see cref="MD5Length.L32"/>.</param>
        /// <returns></returns>
        public static string Md5(string srcString, MD5Length length = MD5Length.L32)
        {
            Check.Argument.IsNotEmpty(srcString, nameof(srcString));

            string str_md5_out = string.Empty;
            using (MD5 md5 = MD5.Create())
            {
                byte[] bytes_md5_in = Encoding.UTF8.GetBytes(srcString);
                byte[] bytes_md5_out = md5.ComputeHash(bytes_md5_in);

                str_md5_out = length == MD5Length.L32
                    ? BitConverter.ToString(bytes_md5_out)
                    : BitConverter.ToString(bytes_md5_out, 4, 8);

                str_md5_out = str_md5_out.Replace("-", "");
                return str_md5_out;
            }
        }
        #endregion

调用结果

        public static void MD5_Test()
        {
            var srcString = "追逐时光者";

            var hashed = EncryptProvider.Md5(srcString);

            Console.WriteLine("MD5加密结果:" + hashed);
        }

RSA加密&解密

封装方法

        /// <summary>
        /// RSA encrypt
        /// </summary>
        /// <param name="publicKey">public key</param>
        /// <param name="srcString">src string</param>
        /// <param name="padding">rsa encryptPadding <see cref="RSAEncryptionPadding"/> RSAEncryptionPadding.Pkcs1 for linux/mac openssl </param>
        /// <param name="isPemKey">set key is pem format,default is false</param>
        /// <returns>encrypted string</returns>
        public static string RSAEncrypt(string publicKey, string srcString, RSAEncryptionPadding padding, bool isPemKey = false)
        {
            Check.Argument.IsNotEmpty(publicKey, nameof(publicKey));
            Check.Argument.IsNotEmpty(srcString, nameof(srcString));
            Check.Argument.IsNotNull(padding, nameof(padding));

            RSA rsa;
            if (isPemKey)
            {
                rsa = RsaProvider.FromPem(publicKey);
            }
            else
            {
                rsa = RSA.Create();
                rsa.FromJsonString(publicKey);
            }

            using (rsa)
            {
                var maxLength = GetMaxRsaEncryptLength(rsa, padding);
                var rawBytes = Encoding.UTF8.GetBytes(srcString);

                if (rawBytes.Length > maxLength)
                {
                    throw new OutofMaxlengthException($"'{srcString}' is out of max encrypt length {maxLength}", maxLength, rsa.KeySize, padding);
                }

                byte[] encryptBytes = rsa.Encrypt(rawBytes, padding);
                return encryptBytes.ToHexString();
            }
        }
        

        /// <summary>
        /// RSA decrypt
        /// </summary>
        /// <param name="publicKey">public key</param>
        /// <param name="srcString">src string</param>
        /// <param name="padding">rsa encryptPadding <see cref="RSAEncryptionPadding"/> RSAEncryptionPadding.Pkcs1 for linux/mac openssl </param>
        /// <param name="isPemKey">set key is pem format,default is false</param>
        /// <returns>encrypted string</returns>
        public static string RSADecrypt(string privateKey, string srcString, RSAEncryptionPadding padding, bool isPemKey = false)
        {
            Check.Argument.IsNotEmpty(privateKey, nameof(privateKey));
            Check.Argument.IsNotEmpty(srcString, nameof(srcString));
            Check.Argument.IsNotNull(padding, nameof(padding));

            RSA rsa;
            if (isPemKey)
            {
                rsa = RsaProvider.FromPem(privateKey);
            }
            else
            {
                rsa = RSA.Create();
                rsa.FromJsonString(privateKey);
            }

            using (rsa)
            {
                byte[] srcBytes = srcString.ToBytes();
                byte[] decryptBytes = rsa.Decrypt(srcBytes, padding);
                return Encoding.UTF8.GetString(decryptBytes);
            }
        }

调用结果

        #region Rsa加密&解密

        public static void Rsa_Encrypt_Decrypt_Test(RsaSize size)
        {
            var rsaKey = EncryptProvider.CreateRsaKey(size);
            var srcString = "追逐时光者";
            var encrypted = EncryptProvider.RSAEncrypt(rsaKey.PublicKey, srcString);
            Console.WriteLine("RSA加密结果:" + encrypted);

            Console.WriteLine("\r\n");

            var decrypted = EncryptProvider.RSADecrypt(rsaKey.PrivateKey, encrypted);
            Console.WriteLine("RSA解密结果:" + decrypted);
        }

        #endregion

DES加密&解密

封装方法

        /// <summary>
        /// DES encrypt
        /// </summary>
        /// <param name="data">Raw data byte array</param>
        /// <param name="key">Key, requires 24 bits</param>
        /// <param name="vector">IV,requires 8 bits</param>
        /// <returns>Encrypted byte array</returns>
        public static byte[] DESEncrypt(byte[] data, string key, string vector)
        {
            Check.Argument.IsNotEmpty(data, nameof(data));
            Check.Argument.IsNotEmpty(key, nameof(key));
            Check.Argument.IsEqualLength(key.Length, 24, nameof(key));
            Check.Argument.IsNotEmpty(vector, nameof(vector));
            Check.Argument.IsEqualLength(vector.Length, 8, nameof(vector));

            return DESEncrypt(data, key, CipherMode.CBC, vector);
        }

        /// <summary>
        /// DES encrypt
        /// </summary>
        /// <param name="data">Raw data</param>
        /// <param name="key">Key, requires 24 bits</param>
        /// <param name="cipherMode"><see cref="CipherMode"/></param>
        /// <param name="paddingMode"><see cref="PaddingMode"/> default is PKCS7</param>
        /// <param name="vector">IV,requires 8 bits</param>
        /// <returns>Encrypted byte array</returns>
        private static byte[] DESEncrypt(byte[] data, string key, CipherMode cipherMode, string vector = "", PaddingMode paddingMode = PaddingMode.PKCS7)
        {
            Check.Argument.IsNotEmpty(data, nameof(data));
            Check.Argument.IsNotEmpty(key, nameof(key));
            Check.Argument.IsEqualLength(key.Length, 24, nameof(key));

            using (MemoryStream Memory = new MemoryStream())
            {
                using (TripleDES des = TripleDES.Create())
                {
                    byte[] plainBytes = data;
                    byte[] bKey = new byte[24];
                    Array.Copy(Encoding.UTF8.GetBytes(key.PadRight(bKey.Length)), bKey, bKey.Length);

                    des.Mode = cipherMode;
                    des.Padding = paddingMode;
                    des.Key = bKey;

                    if (cipherMode == CipherMode.CBC)
                    {
                        byte[] bVector = new byte[8];
                        Array.Copy(Encoding.UTF8.GetBytes(vector.PadRight(bVector.Length)), bVector, bVector.Length);
                        des.IV = bVector;
                    }

                    using (CryptoStream cryptoStream = new CryptoStream(Memory, des.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        try
                        {
                            cryptoStream.Write(plainBytes, 0, plainBytes.Length);
                            cryptoStream.FlushFinalBlock();
                            return Memory.ToArray();
                        }
                        catch (Exception ex)
                        {
                            return null;
                        }
                    }
                }
            }
        }
        
        /// <summary>
        /// DES encrypt
        /// </summary>
        /// <param name="data">Raw data byte array</param>
        /// <param name="key">Key, requires 24 bits</param>
        /// <param name="vector">IV,requires 8 bits</param>
        /// <returns>Encrypted byte array</returns>
        public static byte[] DESDecrypt(byte[] data, string key, string vector)
        {
            Check.Argument.IsNotEmpty(data, nameof(data));
            Check.Argument.IsNotEmpty(key, nameof(key));
            Check.Argument.IsEqualLength(key.Length, 24, nameof(key));
            Check.Argument.IsNotEmpty(vector, nameof(vector));
            Check.Argument.IsEqualLength(vector.Length, 8, nameof(vector));

            return DESDecrypt(data, key, CipherMode.CBC, vector);
        }

        /// <summary>
        /// DES decrypt
        /// </summary>
        /// <param name="data">Encrypted data</param>
        /// <param name="key">Key, requires 24 bits</param>
        /// <param name="cipherMode"><see cref="CipherMode"/></param>
        /// <param name="paddingMode"><see cref="PaddingMode"/> default is PKCS7</param>
        /// <returns>Decrypted byte array</returns>
        private static byte[] DESDecrypt(byte[] data, string key, CipherMode cipherMode, string vector = "", PaddingMode paddingMode = PaddingMode.PKCS7)
        {
            Check.Argument.IsNotEmpty(data, nameof(data));
            Check.Argument.IsNotEmpty(key, nameof(key));
            Check.Argument.IsEqualLength(key.Length, 24, nameof(key));

            byte[] encryptedBytes = data;
            byte[] bKey = new byte[24];
            Array.Copy(Encoding.UTF8.GetBytes(key.PadRight(bKey.Length)), bKey, bKey.Length);

            using (MemoryStream Memory = new MemoryStream(encryptedBytes))
            {
                using (TripleDES des = TripleDES.Create())
                {
                    des.Mode = cipherMode;
                    des.Padding = paddingMode;
                    des.Key = bKey;

                    if (cipherMode == CipherMode.CBC)
                    {
                        byte[] bVector = new byte[8];
                        Array.Copy(Encoding.UTF8.GetBytes(vector.PadRight(bVector.Length)), bVector, bVector.Length);
                        des.IV = bVector;
                    }

                    using (CryptoStream cryptoStream = new CryptoStream(Memory, des.CreateDecryptor(), CryptoStreamMode.Read))
                    {
                        try
                        {
                            byte[] tmp = new byte[encryptedBytes.Length];
                            int len = cryptoStream.Read(tmp, 0, encryptedBytes.Length);
                            byte[] ret = new byte[len];
                            Array.Copy(tmp, 0, ret, 0, len);
                            return ret;
                        }
                        catch
                        {
                            return null;
                        }
                    }
                }
            }
        }

调用结果

        #region DES加密&解密

        public static void DES_Encrypt_Decrypt_Test()
        {
            var srcString = "TEST DES Encrypt Decrypt";
            string key = EncryptProvider.CreateDesKey();
            string iv = EncryptProvider.CreateDesIv();
            var srsDatas = Encoding.UTF8.GetBytes(srcString);
            var encrypted = EncryptProvider.DESEncrypt(srsDatas, key, iv);
            Console.WriteLine("DES加密结果:" + encrypted); 
            
            Console.WriteLine("\r\n");

            var decrypted = EncryptProvider.DESDecrypt(encrypted, key, iv);
            var decryptedStr = Encoding.UTF8.GetString(decrypted);
            Console.WriteLine("DES解密结果:" + decryptedStr);
        }

        #endregion

AES加密&解密

封装方法

        /// <summary>
        /// AES encrypt ( no IV)
        /// </summary>
        /// <param name="data">Raw data</param>
        /// <param name="key">Key, requires 32 bits</param>
        /// <returns>Encrypted string</returns>
        public static string AESEncrypt(string data, string key)
        {
            Check.Argument.IsNotEmpty(data, nameof(data));
            Check.Argument.IsNotEmpty(key, nameof(key));
            Check.Argument.IsEqualLength(key.Length, 32, nameof(key));

            using (MemoryStream memory = new MemoryStream())
            {
                using (Aes aes = Aes.Create())
                {
                    byte[] plainBytes = Encoding.UTF8.GetBytes(data);
                    byte[] bKey = new byte[32];
                    Array.Copy(Encoding.UTF8.GetBytes(key.PadRight(bKey.Length)), bKey, bKey.Length);

                    aes.Mode = CipherMode.ECB;
                    aes.Padding = PaddingMode.PKCS7;
                    aes.KeySize = 256;
                    aes.Key = bKey;

                    using (CryptoStream cryptoStream = new CryptoStream(memory, aes.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        try
                        {
                            cryptoStream.Write(plainBytes, 0, plainBytes.Length);
                            cryptoStream.FlushFinalBlock();
                            return Convert.ToBase64String(memory.ToArray());
                        }
                        catch (Exception ex)
                        {
                            return null;
                        }
                    }
                }
            }
        }
        
        /// <summary>
        /// AES decrypt( no IV)
        /// </summary>
        /// <param name="data">Encrypted data</param>
        /// <param name="key">Key, requires 32 bits</param>
        /// <returns>Decrypted string</returns>
        public static string AESDecrypt(string data, string key)
        {
            Check.Argument.IsNotEmpty(data, nameof(data));
            Check.Argument.IsNotEmpty(key, nameof(key));
            Check.Argument.IsEqualLength(key.Length, 32, nameof(key));

            byte[] encryptedBytes = Convert.FromBase64String(data);
            byte[] bKey = new byte[32];
            Array.Copy(Encoding.UTF8.GetBytes(key.PadRight(bKey.Length)), bKey, bKey.Length);

            try
            {
                byte[] decryptedData = null; // decrypted data

                using (MemoryStream memory = new MemoryStream(encryptedBytes))
                {
                    using (Aes aes = Aes.Create())
                    {
                        aes.Mode = CipherMode.ECB;
                        aes.Padding = PaddingMode.PKCS7;
                        aes.KeySize = 256;
                        aes.Key = bKey;

                        using (CryptoStream decryptor = new CryptoStream(memory, aes.CreateDecryptor(), CryptoStreamMode.Read))
                        {
                            using (MemoryStream tempMemory = new MemoryStream())
                            {
                                byte[] buffer = new byte[1024];
                                Int32 readBytes = 0;
                                while ((readBytes = decryptor.Read(buffer, 0, buffer.Length)) > 0)
                                {
                                    tempMemory.Write(buffer, 0, readBytes);
                                }

                                decryptedData = tempMemory.ToArray();
                                return Encoding.UTF8.GetString(decryptedData);
                            }
                        }
                    }
                }
            }
            catch
            {
                return null;
            }
        }

调用结果

        #region AES加密&解密

        public static void Aes_Encrypt_Decrypt_Test()
        {
            var aesKey = EncryptProvider.CreateAesKey();
            var key = aesKey.Key;

            var srcString = "追逐时光者";

            var encrypted = EncryptProvider.AESEncrypt(srcString, key);
            Console.WriteLine("AES加密结果:" + encrypted);

            Console.WriteLine("\r\n");

            var decrypted = EncryptProvider.AESDecrypt(encrypted, key);
            Console.WriteLine("AES解密结果:" + decrypted);
        }

        #endregion

项目源码地址

更多项目实用功能和特性欢迎前往项目开源地址查看👀,别忘了给项目一个Star支持💖。

GitHub - myloveCc/NETCore.Encrypt: NETCore encrypt and decrypt tool,Include aes,des,rsa,md5,sha1,sha256,sha384,sha512

优秀项目和框架精选

该项目已收录到C#/.NET/.NET Core优秀项目和框架精选中,关注优秀项目和框架精选能让你及时了解C#、.NET和.NET Core领域的最新动态和最佳实践,提高开发工作效率和质量。坑已挖,欢迎大家踊跃提交PR推荐或自荐(让优秀的项目和框架不被埋没🤞)。

https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md

DotNetGuide技术社区交流群

  • DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目推荐、招聘资讯和解决问题的平台。
  • 在这个社区中,开发者们可以分享自己的技术文章、项目经验、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。
  • 我们致力于构建一个积极向上、和谐友善的.NET技术交流平台,为广大.NET开发者带来更多的价值和成长机会。

欢迎加入DotNetGuide技术社区微信交流群👪

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

源码分析Mybatis拦截器(Interceptor)拦截saveBatch()获取不到实体id的原因

1.背景 由于业务需求想在Mybatis拦截器层面获取insert后实体id去做相关业务。但是发现执行saveBatch()方法时&#xff0c;获取参数实体的时候&#xff0c;拿不到自增id。但是save()方法可以。 save方法之所以可以是因为&#xff1a; MybatisPlus的BaseMapper执行insert方法后…

leetcode刷题日志-68.文本左右对齐

给定一个单词数组 words 和一个长度 maxWidth &#xff0c;重新排版单词&#xff0c;使其成为每行恰好有 maxWidth 个字符&#xff0c;且左右两端对齐的文本。 你应该使用 “贪心算法” 来放置给定的单词&#xff1b;也就是说&#xff0c;尽可能多地往每行中放置单词。必要时可…

C语言:结构体

目录 结构体类型的声明 匿名结构体 全局结构体变量 嵌套结构体 访问结构体成员 结构的自引用 结构体变量的定义和初始化 结构体内存对齐 结构体内存对齐规则 修改默认对齐数 #pragma pack(n) offsetof 求结构体成员相对于结构体开头的偏移量的宏。 为什么存在内存…

JavaScript 异步编程

异步的概念 异步&#xff08;Asynchronous, async&#xff09;是与同步&#xff08;Synchronous, sync&#xff09;相对的概念。 在我们学习的传统单线程编程中&#xff0c;程序的运行是同步的&#xff08;同步不意味着所有步骤同时运行&#xff0c;而是指步骤在一个控制流序…

【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…

六大排序(插入排序、希尔排序、冒泡排序、选择排序、堆排序、快速排序)未完

文章目录 排序一、 排序的概念1.排序&#xff1a;2.稳定性&#xff1a;3.内部排序&#xff1a;4.外部排序&#xff1a; 二、插入排序1.直接插入排序2.希尔排序 三、选择排序1.直接选择排序方法一方法二直接插入排序和直接排序的区别 2.堆排序 四、交换排序1.冒泡排序2.快速排序…

论文阅读——DiffusionDet

在目标检测上使用扩散模型 前向过程&#xff1a;真实框-->随机框 后向过程&#xff1a;随机框-->真实框 前向过程&#xff1a; 一般一张图片真实框的数目不同&#xff0c;填补到同一的N个框&#xff0c;填补方法可以是重复真实框&#xff0c;填补和图片大小一样的框&a…

Hive语法,函数--学习笔记

1&#xff0c;排序处理 1.1cluster by排序 &#xff0c;在Hive中使用order by排序时是全表扫描&#xff0c;且仅使用一个Reduce完成。 在海量数据待排序查询处理时&#xff0c;可以采用【先分桶再排序】的策略提升效率。此时&#xff0c; 就可以使用cluster by语法。 cluster…

从能用到好用,国产CPU不是你想象中的样子了?

最近看到了挺多关于国产CPU的评测视频&#xff0c;主要测试了鲲鹏、飞腾、海光、龙芯这四家。作为信创从业者&#xff0c;也想结合日常工作中接触到的国产CPU使用体验&#xff0c;发表些自己的看法。 我看到的评测&#xff0c;主要是采用SPEC CPU2006进行横向对比。SPEC CPU20…

VMware Workstation 与 Device/Credential Guard 不兼容 解决办法

问题描述 问题描述&#xff1a; VMware 启动虚拟机会报错。无法运行。 错误信息&#xff1a;VMware Workstation 与 Device/Credential Guard 不兼容。在禁用 Device/Credential Guard 原因分析&#xff1a; 通常原因是 Window 系统开启了 内置的Hyper-V 虚拟机。 解决方案&…

在 Linux 上搭建 Java Web 项目环境(最简单的进行搭建)

要在 Linux 上安装的程序有 1.JDK (要想运行 java 程序 JDK 是必不可少的) 2.Tomcat &#xff08;HTTP 服务器&#xff0c;是管理 Web 项目的常用工具&#xff09; 3. mysql &#xff08;数据库&#xff09; 一.安装 JDK 博主使用的 Linux 发行版是 centos &#xff0c;cen…

【MySQL--->用户管理】

文章目录 [TOC](文章目录) 一、用户管理表二、基本操作三、用户权限分配给用户某个数据库中某个表的某个权限. grant 权限 on 库.表名 to 用户名主机名. ![在这里插入图片描述](https://img-blog.csdnimg.cn/fe8eb171ef9343c3a09bd64d4f0db5c1.png)分配给用户某个数据库中全部表…

node实战——koa实现文件上传

文章目录 ⭐前言⭐koa实现文件上传⭐foxapi测试⭐总结⭐结束⭐前言 大家好,我是yma16,本文分享关于node实战——node实战——koa实现文件上传。 本文适用对象:前端初学者转node方向,在校大学生,即将毕业的同学,计算机爱好者。 node系列往期文章 node_windows环境变量配置…

【项目管理】中途接手的项目应对实用指南

导读&#xff1a;作为项目经理中途接手项目往往不可避免&#xff0c;为了保证项目成功需要项目经理额外考虑更多的因素和处理相关问题&#xff0c;也往往带来很大的挑战性。本文提供可应对借鉴的思路&#xff0c;在一定程度上可以作为最佳实践。 目录 1、首先、了解项目项目背…

基于SSM的北海旅游网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

支付宝沙箱支付

支付宝沙箱支付 支付宝沙箱&#xff08;Alipay Sandbox&#xff09;是支付宝提供的一个模拟环境&#xff0c;用于开发者在不影响真实交易的情况下进行支付宝相关功能的测试和调试。在软件开发中&#xff0c;沙箱环境通常指的是一个隔离的测试环境&#xff0c;可以模拟真实环境…

【算法挨揍日记】day23——740. 删除并获得点数、LCR 091. 粉刷房子

740. 删除并获得点数 740. 删除并获得点数 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;你可以对它进行一些操作。 每次操作中&#xff0c;选择任意一个 nums[i] &#xff0c;删除它并获得 nums[i] 的点数。之后&#xff0c;你必须删除 所有 等于 nums[i] - 1…

Web3 分布式存储 IPFS(Web3项目一实战之四)

IPFS是一种分布式文件存储协议,它允许世界各地的计算机存储和服务文件作为一个巨大的对等网络的一部分来存储和服务文件。 世界上任何地方的任何计算机都可以下载IPFS软件并开始托管和提供文件。 如果有人在自己的计算机上运行IPFS,并将文件上传到IPFS网络,那么世界上其他任…

一文了解Word2vec 阐述训练流程

一文了解Word2vec 阐述训练流程 个性嵌入&#xff08;Personality Embeddings&#xff09; 词嵌入&#xff08;Word Embeddings&#xff09; 嵌入向量效果分析 语言模型 模型介绍 模型训练 Word2vec训练方法 CBOW方法 Skip-gram方法 CBOW方法与Skip-gram方法总结 重构…

【算法】树形DP③ 监控二叉树 ⭐(二叉树染色二叉树灯饰)!

文章目录 前期知识 & 相关链接例题968. 监控二叉树解法1——标记状态贪心解法2——动态规划 相关练习题目P2458 [SDOI2006] 保安站岗⭐&#xff08;有多个儿子节点&#xff09;&#x1f6b9;LCP 34. 二叉树染色⭐&#xff08;每个节点 单独dp[k 1]数组&#xff09;LCP 64.…