aardio封装库) 微软开源的js引擎(ChakraCore)

前言

做爬虫肯定少不了JavaScript引擎的使用,比如在Python中现在一般用pyexecjs2来执行JavaScript代码,另外还有一些其他执行JavaScript的库:

  • https://github.com/eight04/node_vm2: rpc调用nodejs,需要安装node
  • https://github.com/eight04/deno_vm: rpc调用deno,需要安装deno
  • https://github.com/wistn/pyChakraCore: 调用ChakraCore.dll
aardio执行js

如果本地安装有nodejs,aardio范例里也有rpc调用node执行JavaScript的例子。

但是rpc调用需要依赖本地的nodejs环境,给别人使用也不方便,需要让人先安装nodejs。而ChakraCore这个微软开源的js引擎可以直接调用dll来实现,不需要额外依赖。所以这篇文章我来封装下aardio下的ChakraCore。

有了js引擎的话,又可以利用JavaScript优秀的库资源来丰富aardio的库。比如加载crypt-js给aardio增加一些加密算法(AES、DES等)。

下载地址

封装好的代码可以到github下载

下载地址:https://github.com/kanadeblisst00/aardio-extlibs

开始封装

仓库地址:https://github.com/chakra-core/ChakraCore

编译dll

仓库给出的编译好的dll文件还是2020年的,但是代码最近一直在更新,所以最好是自己编译一个,防止之前的有bug还没修复到。

根据官方给的文档,下载源码后使用vs2017打开Build下的Chakra.Core.sln,然后改一下编译的架构为x86。右键生成解决方案,一步就过了,没有什么坑(最喜欢编译这种项目了)。

生成的dll文件在Build\VcBuild\bin\x86_release下,只需要ChakraCore.dll这一个文件。

封装思路

封装这个库用了不少时间,基本是参考上面pyChakraCore的代码。就不说具体怎么做的(无非就是参考Python的代码和看github和官方文档吗,碰到不会的在搜索一下),有兴趣的可以自己看看库代码,下面说说怎么使用。

测试这个dll无法使用aardio的内存加载,也就是说打包的时候只能带上这个dll,不能直接打包进exe。

案例

说几个简单使用的案例,因为还没有深度使用,后面想到什么在增加吧

例子1
import console; 
import ChakraCore;io.open()var core = ChakraCore();
core.start();console.dump(core.run('(()=>{return Uint8Array.from([1,2,3,4]).buffer;})()'))
console.dump(core.run('(()=>{let a = {"a":1,"b":2};return a;})()'))
console.dump(core.callFunction('pretty', {"a":1,"v":"111"}))
console.dump(core.run('console.log("aaaaa",undefined,null,false,{a:1,b:2},function(){})'))console.pause(true);
例子2

先定义函数再调用

import console; 
import ChakraCore;io.open()var core = ChakraCore();
core.start();core.run("function add(a,b){return a+b;}    
")
var a = 1;
var b = 2;
console.log("a+b=", core.callFunction("add", a,b))console.pause(true);
例子3

注册aardio函数为JavaScript函数,这里以atobbtoa这两个函数为例,ChakraCore没有自带这两个函数,而浏览器有,所以我们用aardio来实现。我在库代码里已经内置了console.logsetTimeout,有兴趣的可以自己看怎么实现。

import console; 
import ChakraCore;
import crypt.bin;
io.open()var core = ChakraCore();
core.start();var btoa = function(ptr_callee, isConstructCall, ptrj_arguments, argumentCount, callbackState){// ptr_callee不知道是什么// isConstructCall表示是不是构造方法// ptrj_arguments是参数的数组// argumentCount是参数的个数// callbackState也不知道是什么var pointerSize = 4;var jStr = ..raw.convert(ptrj_arguments, {ptr p}, pointerSize).p;var aStr = ChakraCore.jValueToString(jStr);var result = crypt.bin.encodeBase64(aStr);var jResult = core.JsCreateString(result,#result,);return jResult;
};var atob = function(ptr_callee, isConstructCall, ptrj_arguments, argumentCount, callbackState){var pointerSize = 4;var jStr = ..raw.convert(ptrj_arguments, {ptr p}, pointerSize).p;var aStr = ChakraCore.jValueToString(jStr);var result = crypt.bin.decodeBase64(aStr);var jResult = core.JsCreateString(result,#result,);return jResult;
}core.registerMethod(btoa, "btoa");
core.registerMethod(atob, "atob");
var result = core.run('btoa("Hello, world")')
console.log("btoa: ", result)
console.log("atob: ", core.callFunction("atob", result))
console.pause(true);

而且比较有意思的是,这样注册的JavaScript函数打印出来的也是function () { [native code] },可惜和浏览器还是有区别,浏览器会加上函数名function btoa() { [native code] }

例子4

调用crypt-js实现下加密AES CBC加密算法

import console; 
import ChakraCore;io.open()var core = ChakraCore();
core.start();core.run($"~\lib\ChakraCore\.res\crypto-js.js")var js = /*
let key = CryptoJS.enc.Utf8.parse("1234567890000000");
let iv = CryptoJS.enc.Utf8.parse("1234567890000000");let s = "Hello World";
let encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(s), key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7
});var eData = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
console.log("加密字符串: ", eData);let decrypted = CryptoJS.AES.decrypt(eData,key, {    iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7
});
let dData= decrypted.toString(CryptoJS.enc.Utf8).toString();
console.log("解密字符串: ", dData);
*/core.run(js)
console.pause(true);

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

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

相关文章

Spring Data JPA数据批量插入、批量更新真的用对了吗

Spring Data JPA系列 1、SpringBoot集成JPA及基本使用 2、Spring Data JPA Criteria查询、部分字段查询 3、Spring Data JPA数据批量插入、批量更新真的用对了吗 前言 在前两篇文章已经介绍过,在使用Spring Data JPA时,DAO层的Respository通过继承J…

BigKey的危害

1.2.1、BigKey的危害 网络阻塞 对BigKey执行读请求时,少量的QPS就可能导致带宽使用率被占满,导致Redis实例,乃至所在物理机变慢 数据倾斜 BigKey所在的Redis实例内存使用率远超其他实例,无法使数据分片的内存资源达到均衡 Redis阻…

Python中动画显示与gif生成

1. 动画生成 主要使用的是 matplotlib.animation ,具体示例如下: import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np fig, ax plt.subplots() t np.linspace(0, 3, 40) g -9.81 v0 12 z g * t**2 / …

等保测评多选模拟题

21、以下哪些是黑客攻击手段?_____(ABCDEFG) A、暴力猜测 B、利用已知漏洞攻击 C、特洛伊木马 D、拒绝服务攻击 E、缓冲区溢出攻击 F、嗅探sniffer G、社会工程 22、计算机病毒的特点有_____。( CD …

NFT是什么?有什么用途?

NFT,即非同质化代币(Non-Fungible Token),是Web3技术的另一个重要应用。与比特币这样的同质化加密货币不同,NFT是独一无二的,每个代币都代表了一个独特的资产或物品。NFT通常基于区块链技术,如以…

新建stm32工程模板步骤

1.先使用keil新建一个project的基本代码 2.stm32启动文件添加 将stm32的启动文件,在原工程当中新建一个Start文件夹把相关的启动文件放到文件夹当中 然后还需要找到下面三个文件 stm32f10x.h是stm32的外设寄存器的声明和定义,后面那两个文件用于配置系…

深度学习 简记

深度学习个人学习简明笔记 待更新 文章目录 1 深度学习概论1.1 基本概念1.2 分类1.3 主要应用 2 神经网络基础2.1 神经网络组成2.2 前向传播与反向传播2.3 超参数2.4 激活函数2.5 优化方法2.5.1 基本梯度下降方法2.5.2 动量梯度下降2.5.3 Adam优化器 3 卷积神经网络(CNN)3.1 基…

【打工日常】Docker部署一款开源和自托管的平铺图像板系统

一、项目介绍1.项目简述Teedy是一个面向个人和企业的开源轻量级文档管理系统。2.项目功能保持组织:一个现代的界面,以保持您的重要文件在一个地方,您的业务操作清晰。上传&搜索:不要花费时间使用该工具,只需上传文档,然后在需要时轻松找到。安全:加密和数据中心将确…

【Docker】搭建一个媒体服务器插件后端API服务 - MetaTube

【Docker】搭建一个媒体服务器插件后端API服务 - MetaTube 前言 本教程基于群晖的NAS设备DS423的docker功能进行搭建,DSM版为 7.2.1-69057 Update 5。 简介 MetaTube 是一个媒体服务器插件,主要用于 Emby 和 Jellyfin 媒体服务器。它的主要功能是从互…

Java 笔记 11:Java 方法相关内容

一、前言 记录时间 [2024-05-01] 系列文章简摘: Java 笔记 01:Java 概述,MarkDown 常用语法整理 Java 笔记 02:Java 开发环境的搭建,IDEA / Notepad / JDK 安装及环境配置,编写第一个 Java 程序 Java 笔记 …

C++之const用法小结

在C中,const关键字具有多种用法,主要用于声明常量,确保某些变量的值在程序运行期间不会被修改。以下是const在C中的一些常见用法: 1.声明常量: 使用const声明的变量是常量,其值在初始化后不能再被修改。 …

OneFlow 概念清单

OneFlow 概念清单 引言 在深度学习框架的丰富生态中,OneFlow 以其独特的架构设计和优化方法吸引了众多研究者和开发者的关注。本文旨在梳理 OneFlow 的核心概念,帮助初学者快速理解其设计理念和使用方法。我们将从基本概念入手,逐步深入到高…

在 PHP中使用 Redis 缓存的方法有哪些

在 PHP 中使用 Redis 作为缓存的方法非常多样化,因为 Redis 提供了丰富的数据结构和命令集。以下是一些常见的 PHP 中使用 Redis 缓存的方法: 字符串缓存 Redis 最基本的数据结构是字符串(string),你可以用它来缓存简…

【数据结构】链表专题2

前言 本篇博客继续探讨有关链表的专题,这片博客的题,提前打个预防针,有点意思哦,哈哈哈,话不多说,进入正文 💓 个人主页:小张同学zkf ⏩ 文章专栏:数据结构 若有问题 评论…

ASP.NET淘宝店主交易管理系统的设计与实现

摘 要 淘宝店主交易管理系统主要采用了ASPACCESS的B/S设计模式,通过网络之间的数据交换来实现客户、商品、交易的管理和对客户、商品、交易统计工作,从而提高淘宝店主在管理网店过程中的工作效率和质量。 系统分为基本资料模块,统计资料模…

“大唐杯”基础知识(部分)

DL:下载 UL:上行链路 在5G系统中:2.1GHZ DL最大4流,UL最大2流;700MHZ DL最大2流,UL最大1流 在5G系统中:在手机开机流程中,负责业务承载建立的过程是PDU会话建立过程 NR中支持基础的4…

北京大学肖臻老师《区块链技术与应用》P14(ETH概述)和P15(ETH账户)

1️⃣ 参考 北京大学肖臻老师《区块链技术与应用》 P14 - ETH概述篇P15 - ETH账户篇 1️⃣4️⃣ETH概述 ① 比特币与以太坊的对比 比特币(区块链 1.0)以太坊(区块链 2.0)出块时间大约10 min十几秒mining puzzle计算密集型Memo…

DRF中的请求入口分析及request对象分析

DRF中的请求入口分析及request对象分析 django restframework框架是在django的基础上又给我们提供了很多方便的功能,让我们可以更便捷基于django开发restful API 1 drf项目 pip install django pip install djangorestframework1.1 核心配置 INSTALLED_APPS [d…

【ARMv8/v9 系统寄存 3 -- system counter CNTPCT_EL0】

文章目录 ARMv8/v9 system countersystem counter读取函数实现 ARMv8/v9 system counter 所有使用Arm处理器的系统中都会包含一个标准化的通用定时器(Generic Timer)框架。这个通用定时器系统提供了一个系统计数器(System Counter&#xff0…

环形链表的经典问题

环形链表 环形链表的介绍链表中是否带环返回链表开始入环的第一个节点 本文主要介绍如何判断一个链表是否是环形链表,以及如何得到环形链表中的第一个节点。 环形链表的介绍 环形链表是一种链表数据结构,环形链表是某个节点的next指针指向前面的节点或指…