当前位置: 首页 > news >正文

iOS MT19937随机数生成,结合AES-CBC加密算法实现。

按处理顺序说明:

1. 生成随机数序列字符串函数

生成方法MT19937,初始种子seed,利用C++库方法,生成:

#include <random> //C++ 库头文件引入NSString * JKJMT19937Seed(uint32_t seed) {NSLog(@"MT19937Seed种子:%u",seed);NSMutableArray *ranVlues = [NSMutableArray array];std::mt19937 rngCPluc2(seed);for (int i = 0; i < 64; ++i) {//连续生产64个随机数unsigned long ranValue = rngCPluc2();NSNumber *rngVal = [NSNumber numberWithUnsignedLong:ranValue];[ranVlues addObject:rngVal];}NSString *ranSeriesStr = [ranVlues componentsJoinedByString:@""];NSLog(@"随机数值序列拼接字符串key1 = %@",ranSeriesStr);return ranSeriesStr;
}

2. 对第一部中的随机数序列字符串进行sha256加密,得到64字节的一个数据流函数。

#import <CommonCrypto/CommonCrypto.h>//加密头文件NSString * sha256String(NSString *inputString) {const char *str = inputString.UTF8String;uint8_t buffer[CC_SHA256_DIGEST_LENGTH];CC_SHA256(str, (CC_LONG)strlen(str), buffer);NSMutableString *strM = [NSMutableString string];for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {[strM appendFormat:@"%02x", buffer[i]];}return [strM copy];
}

 3. AES-CBC加密解密方法

/*CCCrypt方法提供了CBC 和 ECB 两种AES加密模式,如果不传参数,kCCOptionECBMode,则默认即使CBC模式加密。ECB模式不是一种可靠安全的加密模式,推荐使用CBC模式。另外也可以通过其他的库或者方法实现GCM等方式的AES加密。在后面的代码块中翻入方法。
*/
NSData *aesCBCEncrypt(NSData *inputData, NSData *keyData, NSData *ivData) {NSData *key = keyData;// 准备一个初始化向量(IV),IV 的长度需要与 AES 加密模式匹配// 在 AES-CBC 模式下,IV 的长度通常为 AES 块大小(16 字节)NSData *iv = ivData;// 创建一个用于存储加密后数据的 NSMutableData 对象NSMutableData *encryptedData = [NSMutableData dataWithLength:inputData.length + kCCBlockSizeAES128];size_t encryptedDataLength = 0;// 使用 AES-256 加密(CBC)CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES,kCCOptionPKCS7Padding,key.bytes, key.length,iv.bytes, // 无需传入 IVinputData.bytes, inputData.length,encryptedData.mutableBytes, encryptedData.length,&encryptedDataLength);if (cryptStatus == kCCSuccess) {encryptedData.length = encryptedDataLength;return encryptedData;} else {NSLog(@"AES-256 加密失败");return nil;}
}NSData *aesCBCDecrypt(NSData *encryptedData, NSData *keyData, NSData *ivData) {// 准备一个初始化向量(IV)// 在 AES-CBC 模式下,IV 的长度通常为 AES 块大小(16 字节)NSData *iv = ivData;// 创建一个用于存储解密后数据的 NSMutableData 对象NSMutableData *decryptedData = [NSMutableData dataWithLength:encryptedData.length];size_t decryptedDataLength = 0;// 进行 AES 解密CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES,kCCOptionPKCS7Padding,keyData.bytes, keyData.length,iv.bytes, // 传入 IVencryptedData.bytes, encryptedData.length,decryptedData.mutableBytes, decryptedData.length,&decryptedDataLength);if (cryptStatus == kCCSuccess) {decryptedData.length = decryptedDataLength;return decryptedData;} else {NSLog(@"AES 解密失败");return nil;}
}

/*
    CCCrypt方法提供了CBC 和 ECB 两种AES加密模式,
    如果不传参数,kCCOptionECBMode,则默认即使CBC模式加密。
    ECB模式不是一种可靠安全的加密模式,推荐使用CBC模式。
    另外也可以通过其他的库或者方法实现GCM等方式的AES加密。在后面的代码块中翻入方法。
*/

4. 前三个步骤已经完成了加密的基本算法代码,接下来直接示例实现一个传参加密:

- (NSString *)EncryptStringFromtServiceStartMap:(NSDictionary *)json {//补充ts字段。NSMutableDictionary *muJson = [NSMutableDictionary dictionaryWithDictionary:json];NSTimeInterval tsVal =  [[NSDate date] timeIntervalSince1970];[muJson setObject:[NSNumber numberWithInteger:(NSUInteger)(1000* tsVal)] forKey:@"ts"];NSString *jsonString = nil;NSError  *error;NSData   *jsonData = [NSJSONSerialization dataWithJSONObject:muJsonoptions:NSJSONWritingPrettyPrintederror:&error];[self loadAESKeyAndIVData];//获取key和iv。//进行AES加密。NSData *aesData =  aesCBCEncrypt(jsonData, self.aesSHA256keyData, self.aesIVData);//base64再次加密AES-CBC加密后的数据流,返回值作为start_service的参数NSString *base64 =  [aesData base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0];NSString *encryptStr = base64;NSLog(@"jsonContent:%@",muJson);NSLog(@"start_service参数encryptStr = %@",encryptStr);NSData *uncodeAESData = aesCBCDecrypt(aesData, self.aesSHA256keyData, self.aesIVData);if(uncodeAESData){NSError *error = nil;NSDictionary *uncodeDict = [NSJSONSerialization JSONObjectWithData:uncodeAESData options:kNilOptions error:&error];if (error) {NSString *uncodeJSON = [[NSString alloc] initWithData:uncodeAESData encoding:NSUTF8StringEncoding];if(uncodeJSON){NSLog(@"验证解密ServiceMap:%@", uncodeJSON);}else{NSLog(@"验证解密ServiceMap: 解析失败:%@", error);}} else {NSLog(@"验证解密ServiceMap:%@",uncodeDict);}}return encryptStr;
}//初始化AES加密的Key和iv向量数据。
- (void)loadAESKeyAndIVData {// 设置随机种子为 4728423NSString *mt19937Str = JKJMT19937Seed(4728423);NSString *sha256Str = sha256String(mt19937Str);/*密钥,截取sha256的64个字节前面32个字节IV:截取sha256的64个字节前面16个字节*/NSString *keyString = substringWithLength(sha256Str, 32);NSString *ivString  = substringWithLength(sha256Str, 16);//获取AES加密Key_aesSHA256keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];//获取AES加密的IV向量_aesIVData = [ivString dataUsingEncoding:NSUTF8StringEncoding];
}

5. 归纳,完成4的操作,用到了一下两个库,a. C++中的random库,实现mt19937随机数;b. CommonCrypto库,实现AES-CBC对称加密,实现SHA256加密。c. 另外Base64是OC中的NSData(NSDataBase64Encoding)分类方法提供。

#include <random>

#import <CommonCrypto/CommonCrypto.h>

 6. 补充, AES加密如果需要GCM或者其它(非CBC、非ECB)模式的,可能需要用到如下的方法去实现:a. 使用iOS13之后的库, b. 使用第三方库(libsodium-ios为例)

  • a.使用iOS13之后的库代码如下:
//
//  AESEncryptor.swift
//
//  Created by xw.long on 2024/4/7.
//import Foundation
import CryptoKit
import CommonCrypto@available(iOS 13.0, *)
@objc class AESEncryptor: NSObject {func encryptDataUsingCBCMode(data: Data, key: Data, iv: Data) -> Data? {let bufferSize = data.count + kCCBlockSizeAES128var buffer = [UInt8](repeating: 0, count: bufferSize)var numBytesEncrypted: size_t = 0let cryptStatus = data.withUnsafeBytes { dataBytes inkey.withUnsafeBytes { keyBytes iniv.withUnsafeBytes { ivBytes inCCCrypt(CCOperation(kCCEncrypt),CCAlgorithm(kCCAlgorithmAES),CCOptions(kCCOptionPKCS7Padding),keyBytes.baseAddress, key.count,ivBytes.baseAddress,dataBytes.baseAddress, data.count,&buffer, bufferSize,&numBytesEncrypted)}}}if cryptStatus == kCCSuccess {return Data(buffer.prefix(Int(numBytesEncrypted)))} else {print("Error: \(cryptStatus)")return nil}}// 加密方法@objc func encrypt(content: String, key: String, iv: String) -> Data? {guard let keyData = Data(hexString: key),let ivData = Data(hexString: iv),let contentData = content.data(using: .utf8) else {print("AESEncryptor 无法将输入转换为Data")return nil}do {// 创建AES密钥let aesKey = SymmetricKey(data: keyData)// 使用AES-256-GCM加密let sealedBox = try AES.GCM.seal(contentData, using: aesKey, nonce: AES.GCM.Nonce(data: ivData))// 返回加密后的数据return sealedBox.combined} catch {print("AESEncryptor 加密失败: \(error)")return nil}}// 解密方法@objc func decrypt(encryptedData: Data, key: String, iv: String) -> String? {guard let keyData = Data(hexString: key),let ivData = Data(hexString: iv) else {print("AESEncryptor 无法将输入转换为Data")return nil}do {// 创建AES密钥let aesKey = SymmetricKey(data: keyData)// 解密let sealedBox = try AES.GCM.SealedBox(combined: encryptedData)let decryptedData = try AES.GCM.open(sealedBox, using: aesKey)// 将解密后的数据转换为字符串guard let decryptedString = String(data: decryptedData, encoding: .utf8) else {print("解密后的数据无法转换为字符串")return nil}return decryptedString} catch {print("AESEncryptor 解密失败: \(error)")return nil}}// 测试方法@objc static func test() {let content = "hello world"let key = "3891346e92151849d58e70de02a05c596b48afe1ae2bdeedf3e69c661c2ea2ae"let iv = "3891346e9215"if let encryptedData = AESEncryptor().encrypt(content: content, key: key, iv: iv) {print("AESEncryptor 加密后的数据: \(encryptedData.base64EncodedString())")if let decryptedString = AESEncryptor().decrypt(encryptedData: encryptedData, key: key, iv: iv) {print("AESEncryptor 解密后的字符串: \(decryptedString)")}}}}// 十六进制字符串转换为Data扩展
extension Data {init?(hexString: String) {var hexString = hexStringvar data = Data()while hexString.count > 0 {let subIndex = hexString.index(hexString.startIndex, offsetBy: 2)let hexChar = String(hexString[..<subIndex])hexString = String(hexString[subIndex...])guard let byte = UInt8(hexChar, radix: 16) else {return nil}data.append(byte)}self = data}
}+ (void)swiftTest {NSString *originalString = @"3891346e92151849d89070de02a05c596b48a123ae2bdeedf3e69c661c2ea2ae";// 截取新的key和ivNSString *key = [originalString substringToIndex:32];NSString *iv = [originalString substringToIndex:12];// 待加密的内容NSString *content = @"hello world";// 调用加密方法if (@available(iOS 13.0, *)) {NSData *encryptedData = [[AESEncryptor new] encryptWithContent:content key:key iv:iv];// 将加密后的数据转换为Base64字符串NSString *encryptedString = [encryptedData base64EncodedStringWithOptions:0];NSLog(@"加密后的字符串: %@", encryptedString);} else {// Fallback on earlier versions}
}
  • b. 使用第三方库(libsodium-ios为例)

库引用可以通过cocoa-pod方法,在Podfile文件中加入如下代码,并在对应文件目录下执行【pod install】。

 platform :ios, '12.0'

也可以通过github 下载:https://github.com/mochtu/libsodium-ios

# Uncomment the next line to define a global platform for your project

 platform :ios, '12.0'

target 'MYPROJECT' do

  # Comment the next line if you don't want to use dynamic frameworks

  use_frameworks!

  # Pods for MYPROJECT

  pod 'libsodium-ios'

end

post_install do |pi|

    pi.pods_project.targets.each do |t|

      t.build_configurations.each do |config|

        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'

      end

    end

end

下面是库引入之后得代码示例:

#include <sodium.h>NSData *encryptStringWithAES256EStream(NSString *inputString, const unsigned char *nonce, const unsigned char *key) {// 转换输入字符串为NSDataNSData *inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];// 获取输入数据的长度NSUInteger inputLength = inputData.length;// 准备输出缓冲区NSMutableData *encryptedData = [NSMutableData dataWithLength:inputLength];// 产生AES-256-ESTREAM流密码unsigned char stream[inputLength];crypto_stream_aes256estream(stream, inputLength, nonce, key);// 对输入数据进行异或运算,实现加密unsigned char *inputBytes = (unsigned char *)inputData.bytes;unsigned char *encryptedBytes = (unsigned char *)encryptedData.mutableBytes;for (NSUInteger i = 0; i < inputLength; i++) {encryptedBytes[i] = inputBytes[i] ^ stream[i];}return encryptedData;
}+ (void)cryptoTest {// 初始化libsodium库if (sodium_init() == -1) {NSLog(@"libsodium初始化失败");return;}// 长度为16字节的nonceunsigned char nonce[crypto_stream_aes256estream_NONCEBYTES];randombytes_buf(nonce, sizeof(nonce));// 长度为32字节的密钥unsigned char key[crypto_stream_aes256estream_KEYBYTES];randombytes_buf(key, sizeof(key));// 要加密的字符串NSString *inputString = @"hello world";// 使用AES-256-ESTREAM密钥流对字符串进行加密NSData *encryptedData = encryptStringWithAES256EStream(inputString, nonce, key);// 打印加密后的数据NSLog(@"加密后的数据:%@", encryptedData);}

相关文章:

iOS MT19937随机数生成,结合AES-CBC加密算法实现。

按处理顺序说明&#xff1a; 1. 生成随机数序列字符串函数 生成方法MT19937&#xff0c;初始种子seed&#xff0c;利用C库方法&#xff0c;生成&#xff1a; #include <random> //C 库头文件引入NSString * JKJMT19937Seed(uint32_t seed) {NSLog("MT19937Seed种…...

阿里云2024年优惠券获取方法及使用教程详解

阿里云是阿里巴巴集团旗下的云计算服务提供商&#xff0c;是全球领先的云计算及人工智能科技公司之一。提供免费试用、云服务器、云数据库、云安全、云企业应用等云计算服务&#xff0c;以及大数据、人工智能服务、精准定制基于场景的行业解决方案。 阿里云2024年优惠券的获取方…...

hadoop中hdfs的fsimage文件与edits文件

hadoop中hdfs的fsimage文件与edits文件的作用 首先&#xff0c;我们抛出fsimage和edits文件的功能描述。 Fsimage文件: HDFS文件系统元数据的一个永久性的检查点&#xff0c;其中包含HDFS文件系统的 所有目录和文件inode的序列化信息。 Edits文件:存放HDFS文件系统的所有更…...

最新版两款不同版SEO超级外链工具PHP源码

可根据个人感觉喜好自行任意选择不同版本使用&#xff08;版V1或版V2&#xff09; 请将zip文件全部解压缩即可访问&#xff01; 源码全部开源&#xff0c;支持上传二级目录访问 已更新增加大量高质量外链&#xff08;若需要增加修改其他外链请打开txt文件&#xff09;修复优…...

.net框架和c#程序设计第二次测试

一、实验内容 1、设计一个用户登录页面webform1.aspx&#xff0c;效果如下图所示&#xff1a; 2、点击webform1.aspx中“还未注册”连接进入register.aspx&#xff0c;注册页面效果如下图所示&#xff1a;点击用户注册信息到usershow.aspx页面&#xff0c;并显示注册的用户信息…...

芒果YOLOv8改进组合157:动态标签分配ATSS+新颖高效AsDDet检测头组合改进,共同助力VisDrone涨点1.8%,小目标高效涨点

💡本篇内容:【芒果YOLOv8改进ATSS标签分配策略|第三集】芒果YOLOv8改进组合157:动态标签分配ATSS+新颖高效AsDDet检测头组合改进,共同助力VisDrone涨点1.8%,小目标高效涨点 💡🚀🚀🚀本博客 标签分配策略ATSS改进+ 新颖高效AsDDet检测头组合改进,适用于 YOLOv8 …...

自媒体内容创作助手:7款必备ai写作工具一览! #学习方法#科技#其他

这些工具不仅可以快速生成高质量的文本内容&#xff0c;还可以根据用户的需求进行个性化定制。它们可以帮助我们节省大量的时间和精力&#xff0c;让我们更加专注于创意和细节的打磨。本文将为大家详细介绍几个AI写作工具&#xff0c;让你在写作领域更上一层楼。 1.七燕写作 这…...

文心一言 vs GPT-4 -- 全面横向比较

文心一言和GPT-4都是当前非常先进的自然语言处理模型&#xff0c;它们在语言理解、生成和翻译等方面都展现出了出色的能力。以下是对这两个模型的全面横向比较&#xff1a; 核心技术基础&#xff1a; 文心一言&#xff1a;是基于BERT&#xff08;Bidirectional Encoder Repre…...

Leetcode C语言习题

Leetcode习题27&#xff1a;移除元素 题目&#xff1a; 说明&#xff1a; 示例&#xff1a; 题解&#xff1a; 方法一&#xff1a;&#xff08;开辟额外的数组空间&#xff09; 我们可以创建一个新的数组&#xff0c;然后用循环来遍历原数组&#xff0c;将原数组中不为 val…...

比 Nest.js 更优雅的 TS 控制反转策略 - 依赖查找

一、Cabloy5.0 内测预告 Cabloy5.0 采用 TS 对整个全栈框架进行了脱胎换骨般的大重构&#xff0c;并且提供了更加优雅的 ts 控制反转策略&#xff0c;让我们的业务开发更加快捷顺畅 1. 新旧技术栈对比&#xff1a; 后端前端旧版js、egg2.0、mysqljs、vue2、framework7新版ts…...

java算法day43 | 动态规划part05 ● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零

1049. 最后一块石头的重量 II 核心思想&#xff1a; 尽量让石头分成重量相同的两堆&#xff0c;相撞之后剩下的石头最小&#xff0c;这样就化解成01背包问题了。 是不是感觉和昨天讲解的416. 分割等和子集 (opens new window)非常像了。那么分成两堆石头&#xff0c;一堆石头的…...

STM32无刷电机全套开发资料(源码、原理图、PCB工程及说明文档)

目录 1、原理图、PCB、BOOM表 2、设计描述 2.1 前言 2.2 设计电路规范 3、代码 4、资料清单 资料下载地址&#xff1a;STM32无刷电机全套开发资料(源码、原理图、PCB工程及说明文档) 1、原理图、PCB、BOOM表 2、设计描述 2.1 前言 经过一个星期的画PCB&#xff0c;今…...

工地安全监测识别摄像机

工地安全监测识别摄像机是一种在建筑工地和施工现场广泛使用的智能监控设备&#xff0c;主要用于监测施工过程中可能出现的安全隐患和违规行为&#xff0c;以确保工地人员和设备的安全。通过高清摄像头、智能算法和远程监控系统的结合&#xff0c;该摄像机可以实时监测工地各个…...

【零基础学数据结构】顺序表实现书籍存储

目录 书籍存储的实现规划 ​编辑 前置准备&#xff1a; 书籍结构体&#xff1a; 书籍展示的初始化和文件加载 书籍展示的销毁和文件保存 书籍展示的容量检查 书籍展示的尾插实现 书籍展示的书籍增加 书籍展示的书籍打印 书籍删除展示数据 书籍展示修改数据 在指定位置之前…...

【智能算法】黑寡妇优化算法(BWO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2020年&#xff0c;V Hayyolalam等人受到自然界黑寡妇交配行为启发&#xff0c;提出了黑寡妇优化算法&#xff08;Black Widow Optimization Agorithm, BWO&#xff09;。 2.算法原理 2.1算法思想…...

C#-非托管代码

非托管代码是指不受.NET运行时&#xff08;CLR&#xff09;的管理和控制&#xff0c;而是直接由操作系统或其他本机执行环境&#xff08;如C/C编译的代码&#xff09;所执行的代码。以下是一些常见的非托管代码的例子&#xff1a; C/C代码&#xff1a;通过使用C或C等编程语言编…...

计算机视觉之三维重建(7)---多视图几何(下)

文章目录 一、透视结构恢复问题1.1 概述1.2 透视结构恢复歧义1.3 代数方法1.4 捆绑调整 二、P3P问题三、随机采样一致性 一、透视结构恢复问题 1.1 概述 1. 透视结构恢复问题&#xff1a;摄像机为透视相机&#xff0c;内外参数均未知。 2. 问题&#xff1a;已知 n n n 个三维…...

AUTOSAR配置工具开发教程 - 开篇

简介 本系列的教程&#xff0c;主要讲述如何自己开发一套简单的AUTOSAR ECU配置工具。适用于有C# WPF基础的人员。 简易介绍见&#xff1a;如何打造AUTOSAR工具_autosar_mod_ecuconfigurationparameters-CSDN博客 实现版本 AUTOSAR 4.0.3AUTOSAR 4.2.2AUTOSAR 4.4.0 效果 …...

配置VM开机自启动

1. 在此电脑-右键选择“管理”-服务和应用程序-服务中找到VMware Workstation Server服务&#xff08;新版名称也可能是VMware自启动服务&#xff0c;自己找一下&#xff0c;服务属性里有描述信息的&#xff09;&#xff0c;将其启用并选择开机自动启动 新版参考官方文档&…...

工作的第四天

推荐一个软件分配软件 我们看一下如何使用 连接信息 AOC中国官方网站 发现打开 还是这个页面信息&#xff0c;发现最后出现了页面重新定向的问题 我服了 我的码 怎么解决 我想用这个软件 来看看这个软件下载就可以使用 一听到钱我使用的情绪不是很高了 算了不使用 使用…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

Qt的学习(一)

1.什么是Qt Qt特指用来进行桌面应用开发&#xff08;电脑上写的程序&#xff09;涉及到的一套技术Qt无法开发网页前端&#xff0c;也不能开发移动应用。 客户端开发的重要任务&#xff1a;编写和用户交互的界面。一般来说和用户交互的界面&#xff0c;有两种典型风格&…...

GraphRAG优化新思路-开源的ROGRAG框架

目前的如微软开源的GraphRAG的工作流程都较为复杂&#xff0c;难以孤立地评估各个组件的贡献&#xff0c;传统的检索方法在处理复杂推理任务时可能不够有效&#xff0c;特别是在需要理解实体间关系或多跳知识的情况下。先说结论&#xff0c;看完后感觉这个框架性能上不会比Grap…...

Qwen系列之Qwen3解读:最强开源模型的细节拆解

文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...

EEG-fNIRS联合成像在跨频率耦合研究中的创新应用

摘要 神经影像技术对医学科学产生了深远的影响&#xff0c;推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下&#xff0c;基于神经血管耦合现象的多模态神经影像方法&#xff0c;通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里&#xff0c;本研…...

开疆智能Ethernet/IP转Modbus网关连接鸣志步进电机驱动器配置案例

在工业自动化控制系统中&#xff0c;常常会遇到不同品牌和通信协议的设备需要协同工作的情况。本案例中&#xff0c;客户现场采用了 罗克韦尔PLC&#xff0c;但需要控制的变频器仅支持 ModbusRTU 协议。为了实现PLC 对变频器的有效控制与监控&#xff0c;引入了开疆智能Etherne…...

【图片转AR场景】Tripo + Blender + Kivicube 实现图片转 AR 建模

总览 1.将 2D 图片转为立体建模 2. 3. 一、将 2D 图片转为立体建模 1.工具介绍 Tripo 网站 2.找图片 找的图片必须是看起来能够让 AI 有能力识别和推理的&#xff0c;因为现在的AI虽然可以补全但是能力还没有像人的想象力那么丰富。 比如上面这张图片&#xff0c;看起来虽…...

Steam爬取相关游戏评测

## 因为是第一次爬取Steam。所以作为一次记录发出&#xff1b;有所错误欢迎指出。 无时间指定爬取 import requests import time import csv import osappid "553850" # 这里你也可以改成 #appid int(input()) max_reviews 10000 # 想爬多少条 # max_reviews…...

Qt Quick模块功能及架构

Qt 6.0 中的 Qt Quick 模块是构建现代、动态用户界面的核心框架&#xff0c;基于声明式编程&#xff08;QML&#xff09;和 JavaScript&#xff0c;专注于高性能、流畅的动画和跨平台 UI 开发。、 一、主要功能改进 1. Qt Quick 核心架构 QML 引擎升级&#xff1a;Qt 6.0 使用…...