简述 方法其实有很多种的。我先放一些,之后有再遇到对应代码再放上来。 最简单的当然是一个个找进行对比的方法啦~ 当然还是有一些有趣的操作的 实例一:
|
1 2 3 4 5 6 |
import java.util.Arrays; public static int MAX(int[] arr) { Arrays.sort(arr); return arr[arr.length-1]; } |
就是先排序再来得到结果 实例二 这个是菜鸟教程上的一份代码
|
1 2 3 4 5 6 7 8 9 10 11 12 |
import java.util.Arrays; import java.util.Collections; public class Main { public static void main(String[] args) { Integer[] numbers = { 8, 2, 7, 1, 4, 9, 5}; int min = (int) Collections.min(Arrays.asList(numbers)); int max = (int) Collections.max(Arrays.asList(numbers)); System.out.println("最小值: " + min); System.out.println("最大值: " + max); } } |
实例三:
|
1 2 3 4 |
import java.util.Arrays public static int MAX(int[] arr) { return Arrays.stream(arr).max().getAsInt(); } |
from:https://blog.csdn.net/a19990412/article/details/81296234
View DetailsString[]与List的相互转换 1.0 String[]与List的相互转换
|
1 2 |
String[] arr = new String[]{"s1","s2","s3"}; List<String> list = Arrays.asList(arr); |
1.2 List转String[]
|
1 2 3 4 5 |
List<String> list = new ArrayList<String>(); list.add("s1"); list.add("s2"); list.add("s3"); String[] arr = list.toArray(new String[list.size()]); |
字符数组char[]和字符串String之间的转换 2.0 使用String.valueOf()将字符数组转换成字符串
|
1 2 3 4 5 6 7 |
void (){ char[] s={'A','G','C','T'}; String st=String.valueOf(s); System.out.println("This is : "+st); } >> This is : AGCT |
2.1使用.toCharArray()将字符串转换成字符数组
|
1 2 3 4 5 6 7 8 9 10 |
String str="AGCT"; char[] s=str.toCharArray(); for (int i=0;i<str.length();i++){ System.out.println("This s[i] "+i+s[i]); } This s[i] 0 A This s[i] 1 G This s[i] 2 C This s[i] 3 T |
from:https://blog.csdn.net/qq_41076577/article/details/106909006
View Details|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using System; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { // 创建文件 FileStream fs = new FileStream("test.doc", FileMode.OpenOrCreate, FileAccess.ReadWrite); //可以指定盘符,也可以指定任意文件名,还可以为word等文件 StreamWriter sw = new StreamWriter(fs); // 创建写入流 sw.WriteLine("bob hu"); // 写入Hello World sw.Close(); //关闭文件 } } } |
from:https://www.cnblogs.com/thingk/p/3363880.html
View Details补位 string str = "100"; str.PadLeft(5,’0′) 输出:00100 str.PadRight(5, '0') 输出:10000 from:https://www.cnblogs.com/daviddong/p/5949794.html
View Details一 概述 一般地,我们在研究一个问题时,常规的思路是为该问题建模;我们在研究相似问题时,常规思路是找出这些问题的共性和异性。基于该思路,我们如何研究WebApi参数传递问题呢? 首先,从参数本身来说,种类较为多(如int,double,float,string,array,Object等),且有些类型较为复杂(如值类型和引用类型的机制等); 其次,从基于WebApi的Http请求方法来说,种类多且不尽相同(如Get,post,Delete,put,head等),在上一篇文章 :【WebApi系列】浅谈HTTP在WebApi开发中的运用 中,我们简要描述了Http请求的20个方法; ………. 如此复杂且不尽相同,关于WebApi参数传递,我们该选择什么作为切入点来研究呢?基于我们上面提到的研究思路,我们想到了.NET Framework框架,那么,我们来看看基于.NET Framework框架的的WebApi 模板是怎样的呢? 请按图中步骤操作 我们来看看Values控制器是怎样的
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 public string Get(int id) { return "value"; } // POST api/values public void Post([FromBody]string value) { } // PUT api/values/5 public void Put(int id, [FromBody]string value) { } // DELETE api/values/5 public void Delete(int id) { } } |
从Values控制器,我们不难得出如下几个结论: (1)WebApi常规方法为四个:Get,Post,Put和Delete; (2)四种方法的参数可归结为两大类:url传递(Request-url)和Body(Request-body)传递; (3)基于(2),我们将四种方法的参数传递归为两大类,而这两大类又集中在Get和Post中体现了(Put是Get和Post的组合,Delete与Get类似); 其实,分析到现在,我们很容易找得到了研究WebApi参数传递的切入点?研究Get和Post方法参数传递即可。是的,没错,我们本篇文章就是基于Get和Post方法的参数传递,前者对应Request-url,后者对应Reqeust-Body。 二 Get 1 基础数据类型 1.1 方法只含一个形参(参数传得进去) ajax
|
1 2 3 4 5 6 7 8 9 10 |
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", //url: "/api/Default/GetProductDetails?ProductCode=JX80869" url: "/api/Default/GetProductDetails", data: { "ProductCode":"JX80869"} }) }) }) |
Result 总结 (1)当Get方法形参为一个且为基本数据类型时,Get方法能接受外部传递的值 (2)Get传值的本质是通过url字符串拼接,如上两两种url形式的传递的结果都是一样 url形式1
|
1 |
url: "/api/Default/GetProductDetails?ProductCode=JX80869" |
url形式2
|
1 2 |
url: "/api/Default/GetProductDetails", data: { "ProductCode":"JX80869"} |
我们用Goole Chrome来看看结果,发现url形式1和url形式2均一致 (3)Get传递参数本质是url字符串拼接,Request-Head头部传递,Request-Body中不能传递(这是与Post方法的本质区别),我们举两个例子 例子1:我们将形参添加[FromBody]属性后,值传递不进去 例子2:我们用PostMan来测试,发现PostMan中,Get方法参数Body为灰色,是不能选中的 1.2 方法含有多个形参(参数传得进去)
|
1 2 3 4 5 6 7 8 9 |
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", url: "/api/Default/GetProductDetails", data: { "ProductCode": "JX80869","ProductName":"YaGao"} }) }) }) |
result 2 实体对象类型(参数传不进去) model
|
1 2 3 4 5 6 7 8 9 10 11 12 |
1 public class ProductDetail 2 { 3 //产品编码 4 [Required] 5 public string ProductCode { get; set; } 6 //产品名称 7 [Required] 8 public string ProductName { get; set; } 9 //产品价格 10 [Required] 11 public double ProductPrice{ get; set; } 12 } |
ajax
|
1 2 3 4 5 6 7 8 9 10 |
$(document).ready(function () { var productDetail = { "ProductName": "YaGao", "ProductCode": "JX80869", "ProductPrice": 40.5}; $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", url: "/api/Default/ProductDetails", data: productDetail }) }) }) |
result: 分析 3 实体对象和基础数据类型混合(实体传不进去,基础数据能传递进去) ajax
|
1 2 3 4 5 6 7 8 9 |
1 $(document).ready(function () { 2 $("#FindProdcutDetail").click(function () { 3 $.ajax({ 4 type: "Get", 5 url: "/api/Default/GetProductDetails", 6 data: { "_productDetail": "ObjectEntity","ProductName":"YaGao"} 7 }) 8 }) 9 }) |
result 4 最小满足原则(参数传得进去) 所谓“最小满足原则”,指外部参数必须至少满足被调用方法的形参(形参个数,形参类型和形参名字),换句话说,被调用方法具有的形参,外部参数必须传递进来,被调用方法没有 的形参,外部参数传递与否都可以,否则将会产生状态码404错误,用数学集合的思路来理解的话,被调用方法的形参相当于外部参数的子集。如下例子,我们举一个真子集的例子, 即外部传递参数的个数大于被调方法的的形参个数。 Ajax
|
1 2 3 4 5 6 7 8 9 |
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", url: "/api/Default/GetProductDetails", data: {"ProductCode": "JX00034", "ProductName": "YaGao", "ProductPrice": 20.5, "PrudcutType": "Daily Necessities"} }) }) }) |
result 分析:主要原因是路由规则,路由从url里面取参数与aciton参数匹配,直到匹配满足为止,具体详细深入内容,在【WebApi系列】路由章节分析。 5 url长度限制 url参数长度是有一定限制的,当超过一定长度,会报404错误 ajax
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
$(document).ready(function () { $("#FindProdcutDetail").click(function () { $.ajax({ type: "Get", url: "/api/Default/GetProductDetails", data: { "ProductCode": "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } }) }) }) |
result 6 Get规范化 关于Get类型规范化,应注意两点,避免不必要的错误或异常:(1)方法的命名尽量采用:“Get+方法名”的形式 (2)在每个方法上加上特性[HttpGet]。 […]
View Details网上看到很多关于这这个问题的解决方案,但是都不正确,我也恰巧遇到这个问题,所有把正确的解决方案写出来,希望给后来人参考,如有不同意见欢迎指正
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
namespace WebApi.Controllers { [Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { // GET api/values [HttpGet] public ActionResult<IEnumerable<string>> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { return "value"; } // POST api/values [HttpPost] public IActionResult Post([FromBody] string value) { return Ok(value); } // PUT api/values/5 [HttpPut("{id}")] public void Put(int id, [FromBody] string value) { } } } |
|
1 2 3 4 5 6 |
### POST http://localhost:49518/api/values HTTP/1.1 Content-Type: application/json "ddddff" |
|
1 2 3 4 5 6 7 |
var value = '1111';$.ajax({ type: 'POST', contentType: "application/json", url: url, data: value, //如果是 string,int 直接传值 ,如果是模型 就要传对象{} .......省略 }); |
也就是data 不要传{} 对象,直接传字符串或者int from:https://www.cnblogs.com/microestc/p/11003233.html
View Details先问个问题:为什么要使用加密算法? 因为数据在网络中传输时面临4个问题: 窃听 假冒 篡改 事后否认 加密技术就是用来解决“窃听”这个问题的。通常分为两大类:对称加密和非对称加密。 对称加密 概念:对称加密就是加密和解密使用同一个密钥,通常称之为“Session Key ”,这种加密技术在当今被广泛采用,如美国政府所采用的DES加密标准就是一种典型的对称加密算法,它的Session Key长度为56bits。 优点:算法公开、计算量小、加密速度快、加密效率高。适用于需要加密大量数据的场景。 缺点:由于加解密使用同一个密钥,密钥传输的过程不安全,且容易被破解,密钥管理也比较麻烦。例如:不适用于浏览器到服务器的通信,因为密钥一旦发送到浏览器端就很容易暴露。 常见算法:AES,DES,3DES,TDEA,Blowfish,RC5,IDEA 非对称加密 概念:非对称加密就是加密和解密所使用的不是同一个密钥,通常有两个密钥,称为“公钥”和“私钥”,它们两个必需配对使用。“公钥”是指可以对外公布的,“私钥”则不能,只能由持有人一个人知道。 优点:由于加解密是用不同的密钥,私钥并不公开,这样就保证了信息在网络传输中的安全性:即使被拦截也无法解密。非常适用于客户端到服务端的数据传输。例如:支付宝的支付请求,数字签名等。 缺点:加密速度慢,比较耗资源。只适用于少量敏感信息的加密。如果加密大量消息则效率会变得低下。另外,如果动态生成公钥和私钥也比较耗资源。 常见算法:RSA,Elgamal,背包算法,Rabin,D-H,ECC 有人可能会问,上面两类加密方式怎么没有MD5?MD5……严格意义上说不是一种加密算法,因为它不能解密。它只是一种密码散列算法,只是为了校验信息用的:保证信息没有篡改。如:你下载软件或游戏时,在下载页面官方都会提供一个“MD5字符串”,你下载完成后可以用md5工具对下载到的软件md5校验,如果得到的md5串和下载页面的一致,就说明软件或游戏没有被篡改过,可放心使用。 下面我们就一块来实战几种常见的加密方式和散列算法: DES 分类:对称加密 DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class DESUtils { /// <summary> /// 加密数据 /// </summary> /// <param name="text"></param> /// <param name="sessionKey"></param> /// <returns></returns> public static string Encrypt(string text, string sessionKey) { try { var des = GetDESProvider(sessionKey); var bytes = Encoding.Default.GetBytes(text); using var memoryStream = GetMemoryStream(des.CreateEncryptor(), bytes); var result = new StringBuilder(); foreach (var byteItem in memoryStream.ToArray()) { result.AppendFormat("{0:X2}", byteItem); } return result.ToString(); } catch { return string.Empty; } } /// <summary> /// 解密数据 /// </summary> /// <param name="ciphertext"></param> /// <param name="sessionKey"></param> /// <returns></returns> public static string Decrypt(string ciphertext, string sessionKey) { try { var length = ciphertext.Length / 2; var bytes = new byte[length]; for (var i=0; i<length; i++) { var j = Convert.ToInt32(ciphertext.Substring(i * 2, 2), 16); bytes[i] = (byte) j; } var des = GetDESProvider(sessionKey); using var memoryStream = GetMemoryStream(des.CreateDecryptor(), bytes); return Encoding.Default.GetString(memoryStream.ToArray()); } catch { return string.Empty; } } /// <summary> /// 获取DES引擎 /// </summary> /// <param name="sessionKey"></param> /// <returns></returns> private static DESCryptoServiceProvider GetDESProvider(string sessionKey) { var md5Key = MD5Utils.Get32(sessionKey).Substring(8, 8); var des = new DESCryptoServiceProvider { Key = Encoding.ASCII.GetBytes(md5Key), IV = Encoding.ASCII.GetBytes(md5Key) }; return des; } /// <summary> /// 获取内存流 /// </summary> /// <param name="cryptoTransform"></param> /// <param name="bytes"></param> /// <returns></returns> private static MemoryStream GetMemoryStream(ICryptoTransform cryptoTransform, byte[] bytes) { var memoryStream = new MemoryStream(); using var cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write); cryptoStream.Write(bytes, 0, bytes.Length); cryptoStream.FlushFinalBlock(); return memoryStream; } } } |
AES 分类:对称加密 高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class AESUtils { /// <summary> /// 默认Key /// </summary> const string KEY = "E10ADC3949BA59AB"; /// <summary> /// 默认偏移量 /// </summary> const string IV = "BE56E057F20F883E"; /// <summary> /// 加密 /// </summary> /// <param name="text"></param> /// <param name="key"></param> /// <param name="iv"></param> /// <returns></returns> public static string Encrypt(string text, string key = KEY, string iv = IV) { var bytes = Encoding.UTF8.GetBytes(text); var result = Origin(bytes, false, key, iv); return Convert.ToBase64String(result, 0, result.Length); } /// <summary> /// 解密 /// </summary> /// <param name="ciphertext"></param> /// <param name="key"></param> /// <param name="iv"></param> /// <returns></returns> public static string Decrypt(string ciphertext, string key = KEY, string iv = IV) { var bytes = Convert.FromBase64String(ciphertext); var result = Origin(bytes, true, key, iv); if (result.Length < 1) return string.Empty; return Encoding.UTF8.GetString(result); } /// <summary> /// 底层方法 /// </summary> /// <param name="bytes"></param> /// <param name="isDecrypt"></param> /// <param name="key"></param> /// <param name="iv"></param> /// <returns></returns> private static byte[] Origin(byte[] bytes, bool isDecrypt, string key = KEY, string iv = IV) { try { var keyBytes = Encoding.UTF8.GetBytes(key); var ivBytes = Encoding.UTF8.GetBytes(iv); var rijndaelManaged = new RijndaelManaged { BlockSize = 128, KeySize = 256, FeedbackSize = 128, Padding = PaddingMode.PKCS7, Key = keyBytes, IV = ivBytes, Mode = CipherMode.CBC }; var cryptoTransform = isDecrypt ? rijndaelManaged.CreateDecryptor() : rijndaelManaged.CreateEncryptor(); var result = cryptoTransform.TransformFinalBlock(bytes, 0, bytes.Length); return result; } catch { return new byte[] { }; } } } } |
RSA 分类:非对称加密 RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。RSA就是他们三人姓氏开头字母拼在一起组成的。RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class RSAUtils { /// <summary> /// 加密 /// </summary> /// <param name="text">明文</param> /// <param name="publicKey">公钥</param> /// <returns>密文</returns> public static string Encrypt(string text, string publicKey) { var blockSize = 256; // 加密块大小,越大越慢 var bytes = Encoding.UTF8.GetBytes(text); var length = bytes.Length; // rsa实例 var rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(publicKey); var offSet = 0; // 游标 var i = 0; byte[] cache; var ms = new MemoryStream(); while (length - offSet > 0) { var len = length - offSet > blockSize ? blockSize : length - offSet; var temp = new byte[len]; Array.Copy(bytes, offSet, temp, 0, len); cache = rsa.Encrypt(bytes, false); ms.Write(cache, 0, cache.Length); i++; offSet = i * blockSize; } var cipherBytes = ms.ToArray(); return Convert.ToBase64String(cipherBytes); } /// <summary> /// RSA解密 /// </summary> /// <param name="ciphertext">密文</param> /// <param name="privateKey">私钥</param> /// <returns>明文</returns> public static string Decrypt(string ciphertext, string privateKey) { var blockSize = 256; var bytes = Convert.FromBase64String(ciphertext); var length = bytes.Length; // rsa实例 var rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(privateKey); var offSet = 0; // 游标 var i = 0; byte[] cache; var ms = new MemoryStream(); while (length - offSet > 0) { var len = length - offSet > blockSize ? blockSize : length - offSet; var temp = new byte[len]; Array.Copy(bytes, offSet, temp, 0, len); cache = rsa.Decrypt(temp, false); ms.Write(cache, 0, cache.Length); i++; offSet = i * blockSize; } var cipherBytes = ms.ToArray(); return Encoding.UTF8.GetString(cipherBytes); } } } |
生成公钥/密钥的方法(只适用于C#,其他编程语言使用需要转换)
|
1 2 3 |
var rsa = new RSACryptoServiceProvider(); var publicKey = rsa.ToXmlString(false); var privateKey = rsa.ToXmlString(true); |
MD5 分类:散列算法 MD5信息摘要算法(MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
using System; using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class MD5Utils { /// <summary> /// 获取16位散列值 /// </summary> /// <param name="text"></param> /// <returns></returns> public static string Get16(string text) { return Get32(text).Substring(7, 16); } /// <summary> /// 获取32位散列值 /// </summary> /// <param name="text"></param> /// <returns></returns> public static string Get32(string text) { using var md5 = MD5.Create(); var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(text)); var result = BitConverter.ToString(hash); return result.Replace("-", "").ToUpper(); } /// <summary> /// 获取16位散列值 v2 /// </summary> /// <param name="text"></param> /// <returns></returns> public static string Get16v2(string text) { return Get32v2(text).Substring(7, 16); } /// <summary> /// 获取32位散列值 /// </summary> /// <param name="text">字符串</param> /// <returns></returns> public static string Get32v2(string text) { var md5 = new MD5CryptoServiceProvider(); var hash = md5.ComputeHash(Encoding.Default.GetBytes(text)); var resutl = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { resutl.Append(hash[i].ToString("x2")); } return resutl.ToString().ToUpper(); } } } |
SHA-2 分类:散列算法 SHA-2,名称来自于安全散列算法2(英语:Secure Hash Algorithm 2)的缩写,一种密码散列函数算法标准,由美国国家安全局研发,由美国国家标准与技术研究院(NIST)在2001年发布。属于SHA算法之一,是SHA-1的后继者。其下又可再分为六个不同的算法标准,包括了:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
using System.Security.Cryptography; using System.Text; namespace EncryptionPractice.Utils { public class SHAUtils { /// <summary> /// SHA256加密 /// </summary> /// <param name="data"></param> /// <returns></returns> public static string Encrypt(string data) { var bytes = Encoding.UTF8.GetBytes(data); var hash = SHA256.Create().ComputeHash(bytes); var result = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { result.Append(hash[i].ToString("x2")); } return result.ToString(); } } } |
欢迎转载,请注明出处:龙生时代
View Details工作中需要根据身份证获取性别、出生日期及年龄,且要还要支持15位长度的身份证号码,网上搜索了一下,经过测试好像多少存在点问题,干脆自已写一个。 CertificateNo.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package com.bijian.study; import java.util.Calendar; import java.util.regex.Pattern; /** * 根据身份证获取性别、出生日期、年龄,支持15、18位身份证 */ public class CertificateNo { public ResultDTO parseCertificateNo(String certificateNo) { ResultDTO resultDTO = new ResultDTO(); String myRegExpIDCardNo = "^\\d{6}(((19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}([0-9]|x|X))|(\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}))$"; boolean valid=Pattern.matches(myRegExpIDCardNo,certificateNo)||(certificateNo.length() == 17 && Pattern.matches(myRegExpIDCardNo,certificateNo.substring(0,15))); if(!valid){ resultDTO.setStatueMessage("证件号码不规范!"); return resultDTO; } int idxSexStart = 16; int birthYearSpan = 4; //如果是15位的证件号码 if(certificateNo.length() == 15) { idxSexStart = 14; birthYearSpan = 2; } //性别 String idxSexStr = certificateNo.substring(idxSexStart, idxSexStart + 1); int idxSex = Integer.parseInt(idxSexStr) % 2; String sex = (idxSex == 1) ? "M" : "F"; resultDTO.setSex(sex); //出生日期 String year = (birthYearSpan == 2 ? "19" : "") + certificateNo.substring(6, 6 + birthYearSpan); String month = certificateNo.substring(6 + birthYearSpan, 6 + birthYearSpan + 2); String day = certificateNo.substring(8 + birthYearSpan, 8 + birthYearSpan + 2); String birthday = year + '-' + month + '-' + day; resultDTO.setBirthday(birthday); //年龄 Calendar certificateCal = Calendar.getInstance(); Calendar currentTimeCal = Calendar.getInstance(); certificateCal.set(Integer.parseInt(year), Integer.parseInt(month)-1, Integer.parseInt(day)); int yearAge = (currentTimeCal.get(currentTimeCal.YEAR)) - (certificateCal.get(certificateCal.YEAR)); certificateCal.set(currentTimeCal.get(Calendar.YEAR), Integer.parseInt(month)-1, Integer.parseInt(day)); int monthFloor = (currentTimeCal.before(certificateCal) ? 1 : 0); resultDTO.setAge(yearAge - monthFloor); return resultDTO; } } |
ResultDTO.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package com.bijian.study; public class ResultDTO { private String statueMessage; private String sex; private String birthday; private int age; public String getStatueMessage() { return statueMessage; } public void setStatueMessage(String statueMessage) { this.statueMessage = statueMessage; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { String res = ""; if(this.statueMessage != null) { res += this.statueMessage; }else { res += "sex:" + this.sex + ",birthday:" + this.birthday + ",age:" + this.age; } return res; } } |
CertificateNoTest.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
package com.bijian.test; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; import com.bijian.study.CertificateNo; import com.bijian.study.ResultDTO; /** * 说明: * 1.身份证信息完全是测试时随便写的,如有雷同,纯属巧合 * 2.写此测试案例的日期是2015-02-08,有测生日当天及前后的案例,后续再运行需更改 */ public class CertificateNoTest { private CertificateNo certificateNo; private ResultDTO resultDTO; @Before public void setUp() throws Exception { certificateNo = new CertificateNo(); } @Test public void test_abnormality_certificateNo_of_18_digit_430522199812623535() { resultDTO = certificateNo.parseCertificateNo("430522199812623535"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_abnormality_certificateNo_of_18_digit_430522198813013210() { resultDTO = certificateNo.parseCertificateNo("430522198813013210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101515() { resultDTO = certificateNo.parseCertificateNo("430522199812101515"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101595() { resultDTO = certificateNo.parseCertificateNo("430522199812101595"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101585() { resultDTO = certificateNo.parseCertificateNo("430522199812101585"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522198810103212() { resultDTO = certificateNo.parseCertificateNo("430522198810103212"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-10-10", resultDTO.getBirthday()); Assert.assertEquals(26, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_before_birthday() { //测试的时间是2015-02-08,表明昨天刚过生日 resultDTO = certificateNo.parseCertificateNo("430522198802073210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-07", resultDTO.getBirthday()); Assert.assertEquals(27, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_birthday() { //测试的时间是2015-02-08,表明当天正好生日 resultDTO = certificateNo.parseCertificateNo("430522198802083210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-08", resultDTO.getBirthday()); Assert.assertEquals(27, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_after_birthday() { //测试的时间是2015-02-08,表明第二天才过生日 resultDTO = certificateNo.parseCertificateNo("430522198802093210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-09", resultDTO.getBirthday()); Assert.assertEquals(26, resultDTO.getAge()); } @Test public void test_abnormality_certificateNo_of_15_digit_130503671401001() { resultDTO = certificateNo.parseCertificateNo("130503671401001"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_normality_certificateNo_of_15_digit_430522760201356() { resultDTO = certificateNo.parseCertificateNo("430522760201356"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1976-02-01", resultDTO.getBirthday()); Assert.assertEquals(39, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_130503670401001() { resultDTO = certificateNo.parseCertificateNo("130503670401001"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1967-04-01", resultDTO.getBirthday()); Assert.assertEquals(47, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_370802940221002() { resultDTO = certificateNo.parseCertificateNo("370802940221002"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1994-02-21", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_370802941031331() { resultDTO = certificateNo.parseCertificateNo("370802941031331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-10-31", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_before_birthday() { //测试的时间是2015-02-08,表明昨天刚过生日 resultDTO = certificateNo.parseCertificateNo("370802940207331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-07", resultDTO.getBirthday()); Assert.assertEquals(21, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_birthday() { //测试的时间是2015-02-08,表明当天正好生日 resultDTO = certificateNo.parseCertificateNo("370802940208331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-08", resultDTO.getBirthday()); Assert.assertEquals(21, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_after_birthday() { //测试的时间是2015-02-08,表明第二天才过生日 resultDTO = certificateNo.parseCertificateNo("370802940209331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-09", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } } |
from:https://www.iteye.com/blog/bijian1013-2184409
View Details错误原因:程序里面没有可调用的方法(程序使用的是 .NET Framework 4.6,但是你自己的系统里面使用的不是 4.6版本) 解决方法:1.安装window sp1 ,下载地址是:https://www.microsoft.com/zh-cn/download/details.aspx?id=5842 2.安装.NET Framework 4.6 ,下载地址是 :https://www.microsoft.com/zh-cn/download/details.aspx?id=49981 3.重启电脑,OK from:https://www.cnblogs.com/soundcode/p/5837673.html
View Details近半年,自己创业做在线教育,近期也打算开发自己的APP,作为一个技术出身的创业者,所以可以在开发APP时自己做技术选型。 但想到还有很多创业者或架构师也面临类似的问题,所以把自己的思考分享给需要的人。 我的客户端经验 笔者2011年毕业于北京交大,2015年下半年开始由操作系统开发转向安卓开发,2016年在搜狐开始使用react-native开发APP。 2017年曾短期在便利蜂参与过三个RN项目的开发,然后去易鑫从事大前端团队的管理,团队开发维护的原生APP,通过搭桥嵌入H5。 2019年初在快陪练负责前端团队,以纯flutter的方式上线了一个iOS版的钢琴资讯APP,且在直播上课APP中的订单模块接入了flutter。 过去半年多,使用uni-app开发了多个跨端小程序,其中uni-app集成了weex跨端APP开发框架,可以一套代码生成h5,各种小程序以及安卓和iOS的原生APP。 不管是原生APP、还是近几年比较热门的RN、weex或flutter跨端开发APP的技术,笔者都在真实项目中使用过。 正因为都用过,所以各自的坑有都进去过,虽然因为学的东西多,导致精力分散,很多技术都是略懂,但是总结一下,相信还是能有一定参考价值的。 移动应用开发的趋势 由于对移动应用的大量需求,很多公司已经把他们应用开发的重心转移到移动应用上了,这是一个不断有更好的技术、平台和框架流入的领域。 移动行业渴望进行一场革命,以遏制移动应用程序开发过程中出现的成本高、耗时长等问题。 因此,该变革以跨平台开发的形式出现。现在,维护代码和开发应用程序对于开发人员来说变得简单且省时。 现在,跨平台应用开发正在创业公司中变得越来越流行,相继出现了多种跨端开发原生APP的技术方案。 除了weex只在阿里系的公司用得多外,react native 和 flutter目前都有大量的公司在使用,并且互相竞争,试图证明自己是跨平台移动应用的最合适的王者。 React native 是 Facebook 2015年开源的,并且很快获得了大众的欢迎。而Google 的 flutter 则是这两年才火起来的新技术,它优势是更好的性能。 不仅对于资金紧张的初创公司,即使是大公司的新项目,初期都需要快速验证产品的可行性,因此多数公司都不会选择原生开发,而是基于跨端技术。 那么对于开发者来说,应该选用哪个跨平台应用程序开发框架比较好呢? 由于采用react native 和 flutter 的技术栈项目最多,所以本文主要分享我作为创业者在做客户端技术选型时,最后采纳的是使用RN还是flutter的过程。 react native vs flutter 环境搭建 从当前两个框架的最新版本来看,搭建原生开发环境都是比较复杂的,相对来讲,flutter要容易一些,特别是搭建Android开发环境。 编程语言 React Native 允许你使用 Javascript 开发应用程序,通过简单配置也可以使用微软维护的Typescript 语言进行开发,克服JS作为动态语言的一些不足。 由谷歌开发的 Flutter 提出了一种名为 Dart 的新编程语言。它对于开发人员来说是新手,但是那些具有 OOP 语言经验的人,比如 C ++ 和 JAVA,可以很容易地学习的。 IDE 和易于编码 如果我们讨论 React Native 的 IDE,那么它几乎支持所有领先的 IDE。然而,Flutter 受 Android studio / IntelliJ 和 visual studio 代码支持。 代码结构 Google 的 Dart 没有模板、样式和数据文件的分离,因此代码变得有点难以理解。 而 Javascript 遵循简单的代码结构,因此开发人员更清楚地理解和编写代码。 性能 因为 React Native 通过 JS […]
View Details