【PostmanJMeter】使用Postman和JMeter进行signature签名

一、前言

​ 有些接口的请求会带上sign(签名)进行请求,各接口对sign的签名内容、方式可能不一样,但一般都是从接口的入参中选择部分内容组成一个字符串,然后再进行签名操作, 将结果赋值给sign; 完整规范的接口文档都会有sign的算法描述。这里通过Postman的Pre-request Script以及JMeter的BeanShell前置处理器进行接口签名的处理。(完整代码在每部分的最后)

被测系统teachSignServer:

Gitee:江苏豪之诺软件科技有限公司/KnowledgeBroadcast - Gitee.com

直接双击运行.exe文件即可(密钥文件与conf.ini需要与exe处于同一文件夹下)

其余工具:

1.bundle.js:https://github.com/joolfe/postman-util-lib/tree/master/postman

使用方式我们在后面使用到了再进行介绍

2.json.jar: https://mvnrepository.com/artifact/org.json/json

选择适合的版本

点击bundle

将下载的jar包置于jmeter的./lib/ext下并重启jmeter

被测接口信息:

接口

URL

Method

Body

签名规则

v0

http://127.0.0.1:5000/api/v0/teachsign

POST

{"AppKey": "z417App","AppVer": "1.0.0","Data": "{"SPhone":"18662255783","EType":0}","DeviceName": "web","DeviceType": "web","Lang": "CN","Sign": "teachsign","TimeStamp": 1625456804}

appkey,timestamp,data,secret四个字段的值拼接,使用32位md5进行签名

v1

http://127.0.0.1:5000/api/v1/teachsign

POST

{"appid": "wxd930u","mch_id": 10100,"device_info": 100,"body": "{"EType":0}","DeviceType": "","nonce_str": "ibuaiVc","sign": "CD198C36632A274C49E5F2F028FA257C","source": null,"ts": 1625456804}

1. 参与签名运算的参数选用入参里边value非空的参数2. 参与签名运算的参数按照ASCII顺序排序3. 组合方式:key=value通过&符连接4. 最后加上盐key=secret(secret在conf.ini中配置,同理后面的私钥与公钥也可在其中进行配置)5. 使用32位md5进行签名,sign的字母全大写

v2

http://127.0.0.1:5000/api/v2/teachsign

POST

{"busId": "","busCnl": "POS","requJnINo": "abceefgghkjlafksdffdsf","reqTxnTm": "16:30:16","serviceCode": "chengxusong","bussJnIno": "Arabic - Bahrain","sign": "fsdfsd","reqTxnDt": "20210907","nonceStr": "Language","sysCnl": "OKPOS","ts": 1631003416}

1. 参与签名运算的参数选用入参里边value非空的参数2. 参与签名运算的参数按照ASCII顺序排序3. 使用private_key签名4. 使用SHA256withRSA进行签名

二、v0接口

1.Postman

获取请求参数并将body的参数转换为json对象

javascript

var Json = JSON.parse(pm.request.body);

获取所需变量并将新的时间戳更新到json对象中

javascript

var TimeStamp = Date.parse(new Date()) / 1000 - 10; Json.TimeStamp = TimeStamp; var AppKey = Json.AppKey; var Data = Json.Data; var secretKey = "a323f9b6-1f04-420e-adb9-b06ty67b0e63";

字符串拼接

javascript

var str = AppKey + TimeStamp + Data + secretKey;

进行md5运算并将生成的hash序列转换为字符串

javascript

var strmd5= CryptoJS.MD5(str).toString();

修改json对象中sign并将md5对象写回body中

javascript

Json.Sign = strmd5; pm.request.body.raw = JSON.stringify(Json); // 将修改后的JSON转换回字符串格式写回到请求体中

完整代码:

javascript

/* vo加密规则: appkey,timestamp,data,secret四个字段的值拼接,使用32位md5加密 */ /* * 获取请求参数 */ var Json = JSON.parse(pm.request.body); // 将body的参数转换为json对象 /* * 获取所需变量 */ var TimeStamp = Date.parse(new Date()) / 1000 - 10; // 获取时间戳 Json.TimeStamp = TimeStamp; // 修改JSON var AppKey = Json.AppKey; var Data = Json.Data; var secretKey = "a323f9b6-1f04-420e-adb9-b06ty67b0e63"; /* * 拼接字符串并加密 */ var str = AppKey + TimeStamp + Data + secretKey; var strmd5= CryptoJS.MD5(str).toString(); // 调用方法进行md5运算并将生成的hash序列转换为字符串 Json.Sign = strmd5; // 修改JSON pm.request.body.raw = JSON.stringify(Json); // 将修改后的JSON写回到请求体中

2.JMeter

在JMeter的时间戳可以直接使用JMeter自带函数在body中获取,当然也可以在BeanShell前置处理器中使用代码获取

/1000是因为JMeter默认生成的时间戳为13位时间戳,我们只需要10位即可。

导包(org.json为第三方jar包)

java

import org.apache.commons.codec.digest.DigestUtils; import org.apache.jmeter.config.*; import org.json.*;

获取请求传入的body,将其转化为Json对象

java

// 获取请求 Arguments arguments = sampler.getArguments(); // 获取请求中的body内容 Argument arg = arguments.getArgument(0); // 获取body的value,并将其转化为JSONObject对象 JSONObject dataobj = new JSONObject(arg.getValue());

获取变量并拼接

java

String TimeStamp = dataobj.optString("TimeStamp"); String AppKey = dataobj.optString("AppKey"); String Data = dataobj.optString("Data"); String secretKey = "a323f9b6-1f04-420e-adb9-b06ty67b0e63"; String str = AppKey + TimeStamp + Data + secretKey;

进行md5运算

java

sign = DigestUtils.md5Hex(str);

修改json对象的sign并转换为字符串写回body中

java

dataobj.put("Sign", sign); // 修改Sign arg.setValue(dataobj.toString()); // 转换为字符串并歇回request-body中

完整代码:

java

import org.apache.commons.codec.digest.DigestUtils; import org.apache.jmeter.config.*; import org.json.*; /* * 获取请求传入的body,将其转化为Json对象 */ // 获取请求 Arguments arguments = sampler.getArguments(); // 获取请求中的body内容 Argument arg = arguments.getArgument(0); // 获取body的value,并将其转化为JSONObject对象 JSONObject dataobj = new JSONObject(arg.getValue()); /* * 获取变量并拼接字符串 */ // 获取变量 String TimeStamp = dataobj.optString("TimeStamp"); String AppKey = dataobj.optString("AppKey"); String Data = dataobj.optString("Data"); String secretKey = "a323f9b6-1f04-420e-adb9-b06ty67b0e63"; // 字符串拼接 String str = AppKey + TimeStamp + Data + secretKey; /* * 签名,更新body */ sign = DigestUtils.md5Hex(str); // md5运算 dataobj.put("Sign", sign); // 修改Sign arg.setValue(dataobj.toString()); // 转换为字符串并写回request-body中

三、v1接口

1.Postman

​ 获取请求参数并将body的参数转换为json对象

javascript

var Json = JSON.parse(pm.request.body);

获取时间戳并修改json对象

javascript

var ts = Date.parse(new Date()) / 1000 - 10; Json.ts = ts;

去除sign参数本身,然后去除值是空的参数

javascript

var keys = []; // 循环遍历JSON for (let k in Json ){ // 排除json中键位sign以及值为空的数据 if (k == 'sign' || !Json[k]){ continue; } keys.push(k); // 生成筛选后的key序列 }

排序

javascript

keys.sort();

拼接字符串

javascript

let keys_str = ''; for (let x of keys){ keys_str += `${x}=${Json[x]}&`; // 使用模版字符串进行拼接 } keys_str = keys_str + "key=a323f9b6-1f04-420e-adb9-b06ty67b0e63";

进行md5运算并将生成的hash序列转换为字母全大写字符串

javascript

var strmd5= CryptoJS.MD5(keys_str).toString().toUpperCase();

修改json对象中sign并将md5对象写回body中

javascript

Json.sign = strmd5; pm.request.body.raw = JSON.stringify(Json);

完整代码:

javascript

/* v1加密规则: 1. 参与签名运算的参数选用入参里边value非空的参数 2. 参与签名运算的参数按照ASCII顺序排序 3. 组合方式:key=value通过&符连接 4. 最后加上key=secret 5. 使用32位md5签名,sign的字母全大写 */ /* * 获取请求参数 */ var Json = JSON.parse(pm.request.body); var ts = Date.parse(new Date()) / 1000 - 10; // 获取时间戳 Json.ts = ts; // 修改json /* * 去除sign参数本身,然后去除值是空的参数 */ var keys = []; // 定义key序列 // 循环遍历JSON for (let k in Json ){ // 排除json中键位sign以及值为空的数据 if (k == 'sign' || !Json[k]){ continue; } keys.push(k); // 生成筛选后的key序列 } /* * 对请求参数排序 */ keys.sort(); /* * 拼接字符串 */ let keys_str = ''; for (let x of keys){ keys_str += `${x}=${Json[x]}&`; // 使用模版字符串进行拼接 } keys_str = keys_str + "key=a323f9b6-1f04-420e-adb9-b06ty67b0e63"; /* * 签名并更新body */ var strmd5= CryptoJS.MD5(keys_str).toString().toUpperCase(); // 调用方法进行md5运算并将生成的hash序列转换为字母全大写字符串 Json.sign = strmd5; // 修改Json pm.request.body.raw = JSON.stringify(Json);

2.JMeter

同样在body中使用内置函数定义时间戳ts

导包

java

import org.apache.commons.codec.digest.DigestUtils; import org.apache.jmeter.config.*; import org.json.*;

获取请求传入的body,将其转化为Json对象

java

// 获取请求 Arguments arguments = sampler.getArguments(); // 获取请求中的body内容 Argument arg = arguments.getArgument(0); // 获取body的value,并将其转化为JSONObject对象 JSONObject dataobj = new JSONObject(arg.getValue());

获取Json的key

java

// 创建list存储body中的key值 List keyArry = new ArrayList(); // 生成迭代对象 Iterator iterator = dataObj.keys(); // 循环key,将其放入list for (String key : iterator) { if (!key.equals("sign") && !key.equals("Sign")) { keyArry.add(key); } }

对list进行排序

java

Collections.sort(keyArry);

字符串拼接

java

String str = ""; for (String s : keyArry) { // log.error(s); String value = dataObj.optString(s); // 剔除值为空或值为null的参数 if (!value.equals("") && !value.equals(null)) { str = str+s+"="+ value+"&"; } } str = str + "key=a323f9b6-1f04-420e-adb9-b06ty67b0e63";

进行md5运算并转换为字母全大写

java

String sign = DigestUtils.md5Hex(str).toUpperCase();

修改json对象的sign并转换为字符串写回body中

java

dataobj.put("sign", sign); // 修改Sign arg.setValue(dataobj.toString()); // 转换为字符串并歇回request-body中

完整代码:

java

import org.apache.commons.codec.digest.DigestUtils; import org.apache.jmeter.config.*; import org.json.*; /* * 获取请求传入的body,将其转化为Json对象 */ // 获取请求 Arguments arguments = sampler.getArguments(); // 获取请求中的body内容 Argument arg = arguments.getArgument(0); // 获取body的value,并将其转化为JSONObject对象 JSONObject dataObj = new JSONObject(arg.getValue()); /* * 获取Json的key进行排序 */ // 创建list存储body中的key值 List keyArry = new ArrayList(); // 生成迭代对象 Iterator iterator = dataObj.keys(); // 循环key,将其放入list for (String key : iterator) { if (!key.equals("sign") && !key.equals("Sign")) { keyArry.add(key); } } /* * 对list进行排序 */ Collections.sort(keyArry); /* * 循环list中的key,读取对应的Value组成字符串 */ String str = ""; for (String s : keyArry) { String value = dataObj.optString(s); // 剔除值为空或值为null的参数 if (!value.equals("") && !value.equals(null)) { str = str+s+"="+ value+"&"; } } str = str + "key=a323f9b6-1f04-420e-adb9-b06ty67b0e63"; /* * 签名并更新body */ String sign = DigestUtils.md5Hex(str).toUpperCase(); // 进行md5运算并转换为字母全大写 dataobj.put("sign", sign); // 修改Sign arg.setValue(dataobj.toString()); // 转换为字符串并写回request-body中

四、v2接口

1.Postman

将下载后的json导入到postman,进入Lib install请求

发送请求,该请求会将bundle.js写入到全局变量中

获取请求参数并将body的参数转换为json对象

javascript

var Json = JSON.parse(pm.request.body);

获取时间戳并修改json对象

javascript

var ts = Date.parse(new Date()) / 1000 - 10; Json.ts = ts;

去除sign参数本身,然后去除值是空的参数

javascript

var keys = []; // 循环遍历JSON for (let k in Json ){ // 排除json中键位sign以及值为空的数据 if (k == 'sign' || !Json[k]){ continue; } keys.push(k); // 生成筛选后的key序列 }

排序

javascript

keys.sort();

拼接字符串

javascript

let keys_str = ''; for (let x of keys){ keys_str += `${x}=${Json[x]}&`; // 使用模版字符串进行拼接 } keys_str = keys_str.slice(0,-1); // 删除最后一个&

导入刚才写入到全局变量的js

javascript

eval(pm.globals.get("pmlib_code"));

由于私钥过长,所以这里把私钥的内容写到环境变量中,私钥内容可在pkcs8_rsa_private_key.pem查看(私钥与公钥可自行更换,在conf.ini中进行配置即可)

获取私钥

javascript

const privatekey = pm.environment.get("privatekey");

加密

javascript

const sha256withrsa = new pmlib.rs.KJUR.crypto.Signature({"alg": "SHA256withRSA"}); // 生成签名对象并制定为SHA256withRSA类型 sha256withrsa.init(privatekey); // 初始化privatekey sha256withrsa.updateString(keys_str); // 更新要签名的数据 const sign = pmlib.rs.hextob64(sha256withrsa.sign()); // 签名并转换为Base64字符串

修改json对象中sign并将md5对象写回body中

javascript

Json.sign = sign; pm.request.body.raw = JSON.stringify(Json); // 将修改后的JSON转换回字符串格式写回到请求体中

完整代码:

javascript

/* v2加密规则: 1. 参与签名运算的参数选用入参里边value非空的参数 2. 参与签名运算的参数按照ASCII顺序排序 3. 使用private_key签名 4. 使用SHA256withRSA进行签名 */ /* * 获取请求参数 */ var Json = JSON.parse(pm.request.body); var ts = Date.parse(new Date()) / 1000 - 10; // 获取时间戳 Json.ts = ts; // 修改json /* * 去除sign参数本身,然后去除值是空的参数 */ var keys = []; // 定义key序列 // 循环遍历JSON for (let k in Json ){ // 排除json中键位sign以及值为空的数据 if (k == 'sign' || !Json[k]){ continue; } keys.push(k); // 生成筛选后的key序列 } /* * 对请求参数排序 */ keys.sort(); /* * 拼接字符串 */ let keys_str = ''; for (let x of keys){ keys_str += `${x}=${Json[x]}&`; // 使用模版字符串进行拼接 } keys_str = keys_str.slice(0,-1); // 删除最后一个& /* * 加密并更新body */ eval(pm.globals.get("pmlib_code")); // 导入写入到全局变量的js const privatekey = pm.environment.get("privatekey"); // 从环境变量获取私钥 const sha256withrsa = new pmlib.rs.KJUR.crypto.Signature({"alg": "SHA256withRSA"}); // 生成签名对象并制定为SHA256withRSA类型 sha256withrsa.init(privatekey); // 初始化privatekey sha256withrsa.updateString(keys_str); // 更新要签名的数据 const sign = pmlib.rs.hextob64(sha256withrsa.sign()); // 签名并转换为Base64字符串 Json.sign = sign; pm.request.body.raw = JSON.stringify(Json);

2.JMeter

同样在body中使用内置函数定义时间戳ts,同时添加用户定义的变量配置元件来存放私钥

导包

java

import org.apache.jmeter.config.*; import org.apache.commons.codec.digest.DigestUtils; import org.json.*; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec;

获取请求传入的body,将其转化为Json对象

java

// 获取请求 Arguments arguments = sampler.getArguments(); // 获取请求中的body内容 Argument arg = arguments.getArgument(0); // 获取body的value,并将其转化为JSONObject对象 JSONObject dataobj = new JSONObject(arg.getValue());

获取Json的key

java

// 创建list存储body中的key值 List keyArry = new ArrayList(); // 生成迭代对象 Iterator iterator = dataObj.keys(); // 循环key,将其放入list for (String key : iterator) { if (!key.equals("sign") && !key.equals("Sign")) { keyArry.add(key); } }

对list进行排序

java

Collections.sort(keyArry);

字符串拼接

java

String str = ""; for (String s : keyArry) { // log.error(s); String value = dataObj.optString(s); // 剔除值为空或值为null的参数 if (!value.equals("") && !value.equals(null)) { str = str+s+"="+ value+"&"; } } //删除最后一个& str = str.substring(0,str.length()-1);

读取私钥

​ java中读取私钥需要删除前面的“-----BEGIN PRIVATE KEY-----”和后面的“-----END PRIVATE KEY-----”,且需要key首尾连接中间无换行或空格。

java

String privateKeyString = vars.get("privateKey"); // 从用户定义的变量中读取私钥 privateKeyString = privateKeyString.replace(" ", ""); // 删除多余的空格 byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyString); // 将Base64解码转化为字符串 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); // 根据给定的编码密钥创建一个新的 PKCS8EncodedKeySpec PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec); // 生成RSA的私钥对象。

创建 Signature 对象并初始化

java

Signature signature = Signature.getInstance("SHA256withRSA"); // 生成SHA256withRSA的Signature 对象 signature.initSign(privateKey); // // 初始化签署签名的私钥

更新要签名的数据

java

signature.update(str.getBytes("UTF-8")); // 更新要签名或验证的字节

签名

java

byte[] signatureBytes = signature.sign(); // 执行签名 String sign = Base64.getEncoder().encodeToString(signatureBytes); // 将签名结果转换为 Base64 字符串

修改json对象的sign并转换为字符串写回body中

java

dataobj.put("sign", sign); // 修改Sign arg.setValue(dataobj.toString()); // 转换为字符串并歇回request-body中

完整代码:

java

import org.apache.jmeter.config.*; import org.apache.commons.codec.digest.DigestUtils; import org.json.*; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; /* * 获取请求传入的body,将其转化为Json对象 */ // 获取请求 Arguments arguments = sampler.getArguments(); // 获取请求中的body内容 Argument arg = arguments.getArgument(0); // 获取body的value,并将其转化为JSONObject对象 JSONObject dataObj = new JSONObject(arg.getValue()); /* * 获取Json的key进行排序 */ // 创建list存储body中的key值 List keyArry = new ArrayList(); // 生成迭代对象 Iterator iterator = dataObj.keys(); // 循环key,将其放入list for (String key : iterator) { if (!key.equals("sign") && !key.equals("Sign")) { keyArry.add(key); // log.error(key); } } // 对list进行排序 Collections.sort(keyArry); /* * 循环list中的key,读取对应的Value组成字符串 */ String str = ""; for (String s : keyArry) { // log.error(s); String value = dataObj.optString(s); if (!value.equals("")) { str = str+s+"="+ value+"&"; } } //删除最后一个& str = str.substring(0,str.length()-1); /* * 读取私钥 */ String privateKeyString = vars.get("privateKey"); // 从用户定义的变量中读取私钥 privateKeyString = privateKeyString.replace(" ", ""); // 删除多余的空格 byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyString); // 将Base64解码转化为字符串 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); // 根据给定的编码密钥创建一个新的 PKCS8EncodedKeySpec PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec); // 生成RSA的私钥对象。 /* * 读创建 Signature 对象并初始化 */ Signature signature = Signature.getInstance("SHA256withRSA"); // 生成SHA256withRSA的Signature 对象 signature.initSign(privateKey); // 初始化签署签名的私钥 // /* * 更新要签名的数据化 */ signature.update(str.getBytes("UTF-8")); // 更新要签名或验证的字节 /* * 签名并更新body */ byte[] signatureBytes = signature.sign(); // 签署所有更新字节的签名 // 将签名结果转换为 Base64 字符串 String sign = Base64.getEncoder().encodeToString(signatureBytes); // 编码为Base64字符串 dataobj.put("sign", sign); // 修改Sign arg.setValue(dataobj.toString()); // 转换为字符串并歇回request-body中

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群: 731789136,里面有各种测试开发资料和技术可以一起交流哦。

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

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

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

相关文章

詹金斯搭建_詹金斯的Maven报告

詹金斯搭建代码质量是一个敏感的话题。 它会影响您的维护成本以及客户满意度。 更不用说您的开发人员使用代码的动力了。 谁想要修复难看的代码,对吗? 讨论代码质量总是需要事实和数字! 因此,这是一个简短的教程,介绍…

Oracle应用容器云的自由

在这篇博客文章中,我将介绍如何部署CloudEE封装在杜克大学应用自由尤伯杯罐子Oracle应用集装箱云端 。 在Oracle Application Container Cloud中进行部署所需的部署工件是一个ZIP归档文件,其中包含应用程序ber-jar和清单文件(manifest.json&…

简洁明了!Java实现单向环形链表以解决约瑟夫环Josepfu问题

文章目录简单介绍代码实现简单介绍 如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表,通俗讲就是让尾节点指向头结点。 单向环形链表应用场景:Josephu(约瑟夫、约瑟夫环)问题&#xf…

荣耀v10Android9新功能,荣耀10、荣耀V10开启安卓9.0内测 日常领跑行业

【PConline 资讯】今天(8月9日)早上10点,荣耀总裁赵明发微博宣布荣耀已经有四款机型面向少部分用户推送安卓9.0内部测试版本。实际上,在8月8日晚上,花粉论坛就已经公布华为4款机型内测安卓 9.0 版本,荣耀手机两款旗舰进入升级名单…

状态模式 设计模式_设计模式:状态

状态模式 设计模式本文将介绍状态设计模式 。 它是行为设计模式之一 。 您无需了解许多理论即可了解模式的主要概念。 该文章将分为几个部分,在其中我将提供有关需要应用该模式的情况,它所具有的利弊以及用法示例的信息。 有时,当对象的内部…

Java中的AES加密和解密(CBC模式)

通过有线方式传输诸如纯文本密码之类的机密数据总是容易受到安全性的影响,始终建议对此类信息进行加密并使用SSL传输这些机密数据.Java为此提供了多种加密算法。在本文中,我们将讨论Java中具有CBC模式的AES(高级加密标准)对称加密…

hiti打印机android驱动,HiTi 打印机 驱动程序下载——更新 HiTi 软件

HiTi 打印机驱动程序下载如何手动下载和更新:你可以通过 %%os%% 或通过执行 Windows 更新获取基本的 HiTi Printer 驱动程序。 内置驱动程序将支持Printer的基本功能,但通常不支持更高级的功能。以下是手动更新这些 HiTi 设备驱动程序的完整指南。程序员: HiTi 类别…

Java实现最小二乘法线性拟合,传感与检测,单臂半桥全桥实验,江南大学自动化

因为作为资源上传不方便我们获取且我想免费分享给有需要的小伙伴,以后所有实验报告都通过文章形式记录输出了,仅供参考,欢迎交流。(最小二乘法代码在文末) 电桥特性曲线: Java实现最小二乘法线性拟合及计算…

android task详解,Android AsyncTask的使用详解

当然,我们在进行耗时操作或者更新UI时,是可以使用匿名线程的,但是此种方式是存在缺陷的:第一,线程的开销较大,如果每个任务都要创建一个线程,那么应用 程序的效率要低很多;第二&…

【Error】IDEA报错:org.jetbrains.jps.builders.java.dependencyView.TypeRepr$PrimitiveType cannot be cast t

错误日志: org.jetbrains.jps.builders.java.dependencyView.TypeRepr$PrimitiveType cannot be cast to org.jetbrains.jps.builders.java.dependencyView.TypeRepr$ClassType 解决方法:

ReSQL的?

大约在2009年创造出来的NoSQL名字标志着从“传统”关系模型的转变。 在2009年之前,有相当多的非关系数据库,但是在最近几年中,我们看到了许多新产品(例如, 我在上一篇文章中可以看到“ NoSQL格局” )。 一般…

数据结构,Java实现递归回溯,寻找出迷宫路线,解决迷宫问题

/*** Author: Yeman* Date: 2021-10-28-22:52* Description:*/ public class Labyrinth {public static void main(String[] args) {//七行八列的迷宫地图int[][] map new int[8][7];//设置墙for (int i 0; i < 7; i) {map[0][i] 1;map[7][i] 1;}for (int i 0; i < …

android动画优缺点,Android动画总结

动画分为三种&#xff1a;View动画、帧动画和属性动画View动画View动画共有四种动画&#xff1a;TranslateAnimation、RotateAnimation、ScaleAnimation和AlphaAnimation。四个动画类都继承于抽象类Animation。名称标签子类效果平移动画TranslateAnimation移动View缩放动画Scal…

Java实现递归回溯,解决八皇后问题,数据结构与算法

文章目录八皇后问题解决思路代码实现运行结果八皇后问题 八皇后问题&#xff0c;是一个古老而著名的问题&#xff0c;是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯贝瑟尔于1848年提出&#xff1a;在8X8格的国际象棋上摆放八个皇后&#xff0c;使其不能互相攻击&#x…

HTML JS正方形轮播,js,html一个页面里面多个页面轮播

这种轮播都是div或者图片的&#xff0c;div能换成iframe显示嵌套网页吗&#xff1f;或者请问有没有其他方法能实现多个页面轮播&#xff1f;我写了三个iframeframeborder"no" border"0" marginwidth"0" marginheight"0" scrolling&quo…

html制作任务计划列表网页,添加计划任务的脚本

在windows中怎样用bat或者vbs添加计划任务..例如.我想在每次开机10分钟后运行windows目录中的XX.exe文件。应该怎么弄写了一个bat的备份脚本&#xff0c;在添加计划任务的时候&#xff0c;出你可以把 运行的帐号制定成管理员&#xff0c;不要任意用户。200分。用批处理或DOS添加…

第一章MCS-51单片机结构,单片机原理、接口及应用

文章目录一、MCS-51单片机内部结构二、CPU三、存储器四、特殊功能寄存器SFR五、时钟电路与复位电路六、引脚功能一、MCS-51单片机内部结构 单片机是在一块芯中集成了CPU、RAM、ROM、定时/计数器和多功能I/O接口等基本部件的大规模集成电路&#xff0c;又称MCU。 51系列单片机…

微信小程序云开发校园社交二手物品跳蚤平台表白动态求助寻物组队

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记&#xff08;微信号csds99202…

传感与检测实验报告,差动变压器的特性测定,江南大学物联网自动化

前些天发现了十分不错的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; public class LeastSquares {public static void matching(…