Lua快速入门教程

news2024/9/23 23:27:57

文章目录

  • 1、Linux安装Lua
  • 2、语法练习
    • 2.1、变量
    • 2.2、循环
    • 2.3、函数
    • 2.4、数组
    • 2.5、迭代器
    • 2.6、Table操作
    • 2.7、Lua 模块与包
    • 2.8、加载机制
    • 2.9、Lua 元表(Metatable)
  • 3、Lua 协同程序(coroutine)
  • 4、文件IO操作
    • 4.1、简单模式
    • 4.2、完全模式
  • 5、错误处理

内容来源菜鸟教程,主要列举一些重要部分和c语言有歧义的部分
https://www.runoob.com/lua/lua-file-io.html

1、Linux安装Lua

1、下载
wget http://www.lua.org/ftp/lua-5.3.0.tar.gz

2、解压
tar zxf lua-5.3.0.tar.gz

3、进入目录
cd lua-5.3.0

4、编译
make linux test

5、拷贝到系统位置
make install

2、测试使用
vi test.lua

print(“hello world”)

保存内容

运行lua脚本
lua test.lua

3、首行加入,直接可以运行
#!/usr/local/bin/lua

2、语法练习

1、… 拼接字符串,可以利用nil来删除表中的值

tal = {ke1 = "val1",ke2 = "val2","val3"}
for k,v in pairs(tal) do
    print(k .. "-" .. v)
end

tal.ke1 = nil

for k,v in pairs(tal) do
    print(k,v)
end

2、lua中数字字符串会默认转换成数字进行操作符运算

tal = {}

tal["key"] = "val"
key = 10
tal[key]  = 10
tal[key] = tal[key] + 22
for k,y in pairs(tal) do
    print(k,y)
end

3、 lua中表中数组下标是从1开始

-- lua中表中数组下标是从1开始
tal = {"key1","key2","key3"}
for key,val in pairs(tal) do
    print("key",key)
end

4、在 Lua 中,函数是被看作是"第一类值(First-Class Value)",函数可以存在变量里

function fun(n)
    if n == 0 then
        return 1
    else
        return n*fun(n-1)
    end
end
print(fun(5))
fun2 = fun
print(fun2(5))

5、function 可以以匿名函数(anonymous function)的方式通过参数传递:

function fun2(tal,fun)
    for key,val in pairs(tal) do
        print(fun(key,val))
    end
end

tal = {key1 = "val1",key2 = "val2",key3 = "val3"}
fun2(tal,
function(key,val)
    return key.."="..val
end
)

2.1、变量

1、Lua 变量有三种类型:全局变量、局部变量、表中的域。

a = 5       -- 全局变量
local b = 5 -- 局部变量

function joke()
    c = 5   -- 全局变量
    local d = 6 -- 局部变量
end

joke()
print(c,d)  --> 5 nil

do 
    local a = 6 -- 局部变量
    b = 6   -- 对局部变量重新赋值
    print(a,b); --> 6 6
end

print(a,b)  --> 5 6

2、赋值语句

a,b = "hello",111
print(a,b)

-- 可以利用这种方式对变量进行交换操作
a,b = 111,222
print(a,b)

a,b = b,a
print(a,b)

3、当变量个数和值的个数不一致时,Lua会一直以变量个数为基础采取以下策略:
a. 变量个数 > 值的个数 按变量个数补足nil
b. 变量个数 < 值的个数 多余的值会被忽略

a, b, c = 0, 1
print(a,b,c)    --> 0   1   nil

a, b = a+1, b+1, b+2    -- value of b+2 is ignored
print(a,b)          --> 1   2

a, b, c = 0
print(a,b,c)        --> 0   nil   nil

2.2、循环

这里只是列举出与c语言不一样的地方

重复执行循环,直到 指定的条件为真时为止

--[ 变量定义 --]
a = 10
--[ 执行循环 --]
repeat
   print("a的值为:", a)
   a = a + 1
until( a > 15 )

Lua 语言中的 goto 语句允许将控制流程无条件地转到被标记的语句处。

local i = 0
::s1:: do
    print(i)
    i = i+1
end

if i == 1 then
    goto s1
end

2.3、函数

可变参数

function add(...)
    local s = 0  
    for i, v in ipairs{...} do   --> {...} 表示一个由所有变长参数构成的数组  
        s = s + v
    end
    return s
end
print(add(1,2,3,4,5))

Lua 中我们可以将函数作为参数传递给函数

myprint = function (param)
    print("##",param,"##")
end

function add(x,y,myp)
    myp(x+y)
end

add(10,20,myprint)

将可变参数赋值给一个变量
我们也可以通过 select(“#”,…) 来获取可变参数的数量

function average(...)
    local arg = {...} -- arg为一个表,可变参
    local result = 0
    for key,val in ipairs(arg) do
        result = result + val
    end
    print("总长度为:",#arg)
    return result/#arg
end

print(average(1,2,3,4,56))

2.4、数组

多维数组
多维数组即数组中包含数组或一维数组的索引键对应一个数组。
以下是一个三行三列的阵列多维数组:

-- 初始化数组
array = {}
for i=1,3 do
   array[i] = {}
      for j=1,3 do
         array[i][j] = i*j
      end
end

-- 访问数组
for i=1,3 do
   for j=1,3 do
      print(array[i][j])
   end
end

不同索引键的三行三列阵列多维数组:

-- 初始化数组
array = {}
maxRows = 3
maxColumns = 3
for row=1,maxRows do
   for col=1,maxColumns do
      array[row*maxColumns +col] = row*col
   end
end

-- 访问数组
for row=1,maxRows do
   for col=1,maxColumns do
      print(array[row*maxColumns +col])
   end
end

2.5、迭代器

多状态的迭代器

local tab = {"c","c++"}

function element(collection)
    local index = 0
    local count = #collection
    -- 闭包函数
    return function ()
        index = index +1
        if(index<=count) then
            return collection[index]
        end
    end
end

for e in element(tab) do
    print(e)
end

2.6、Table操作

Table 连接

fruits = {"banana","orange","apple"}
-- 返回 table 连接后的字符串
print("连接后的字符串 ",table.concat(fruits))

-- 指定连接字符
print("连接后的字符串 ",table.concat(fruits,", "))

-- 指定索引来连接 table
print("连接后的字符串 ",table.concat(fruits,", ", 2,3))

连接后的字符串 bananaorangeapple
连接后的字符串 banana, orange, apple
连接后的字符串 orange, apple

插入和移除

fruits = {"banana","orange","apple"}

-- 在末尾插入
table.insert(fruits,"mango")
print("索引为 4 的元素为 ",fruits[4])

-- 在索引为 2 的键处插入
table.insert(fruits,2,"grapes")
print("索引为 2 的元素为 ",fruits[2])

print("最后一个元素为 ",fruits[5])
table.remove(fruits)
print("移除后最后一个元素为 ",fruits[5])

索引为 4 的元素为 mango
索引为 2 的元素为 grapes
最后一个元素为 mango
移除后最后一个元素为 nil

Table 排序

fruits = {"banana","orange","apple","grapes"}
print("排序前")
for k,v in ipairs(fruits) do
        print(k,v)
end

table.sort(fruits)
print("排序后")
for k,v in ipairs(fruits) do
        print(k,v)
end

排序前
1 banana
2 orange
3 apple
4 grapes
排序后
1 apple
2 banana
3 grapes
4 orange

2.7、Lua 模块与包

模块类似一个封装库,从5.1开始,lua中加入了标准的模块管理机制,可以将一个公共的代码,放入到一个文件中,以API的形式提供,lua使用,变量,函数组成的table表,创建一个模块很简单,就是创建一个table表,将需要导入的数据放入到table表中,然后将其返回

module = {}

module.constant = "这是一个常量"

-- 定义一个函数

function module.func1()
    io.write("这是一个函数")
end

local function func2()
    print("这是一个私有函数")
end

function module.func3()
    func2()
end

return module

使用模块
require 函数
Lua提供了一个名为require的函数用来加载模块。要加载一个模块,只需要简单地调用就可以了。例如:
require(“<模块名>”)或者require “<模块名>”

-- 调用模块
-- 执行 require 后会返回一个由模块常量或函数组成的 table,并且还会定义一个包含该 table 的全局变量。
require("module")

print(module.constant)
module.func3()

或者给加载的模块定义一个别名变量,方便调用:

-- test_module2.lua 文件
-- module 模块为上文提到到 module.lua
-- 别名变量 m
local m = require("module")
 
print(m.constant)
 
m.func3()

2.8、加载机制

对于自定义的模块,模块文件不是放在哪个文件目录都行,函数 require 有它自己的文件路径加载策略,它会尝试从 Lua 文件或 C 程序库中加载模块。
require 用于搜索 Lua 文件的路径是存放在全局变量 package.path 中,当 Lua 启动后,会以环境变量 LUA_PATH 的值来初始这个环境变量。如果没有找到该环境变量,则使用一个编译时定义的默认路径来初始化。
当然,如果没有 LUA_PATH 这个环境变量,也可以自定义设置,在当前用户根目录下打开 .profile 文件(没有则创建,打开 .bashrc 文件也可以),例如把 “~/lua/” 路径加入 LUA_PATH 环境变量里:

#LUA_PATH
export LUA_PATH="~/lua/?.lua;;"

文件路径以 “;” 号分隔,最后的 2 个 “;;” 表示新加的路径后面加上原来的默认路径。

接着,更新环境变量参数,使之立即生效。

source ~/.profile

这时假设 package.path 的值是:

/Users/dengjoe/lua/?.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua

那么调用 require(“module”) 时就会尝试打开以下文件目录去搜索目标。

/Users/dengjoe/lua/module.lua;
./module.lua
/usr/local/share/lua/5.1/module.lua
/usr/local/share/lua/5.1/module/init.lua
/usr/local/lib/lua/5.1/module.lua
/usr/local/lib/lua/5.1/module/init.lua

如果找过目标文件,则会调用 package.loadfile 来加载模块。否则,就会去找 C 程序库。

搜索的文件路径是从全局变量 package.cpath 获取,而这个变量则是通过环境变量 LUA_CPATH 来初始。

搜索的策略跟上面的一样,只不过现在换成搜索的是 so 或 dll 类型的文件。如果找得到,那么 require 就会通过 package.loadlib 来加载它。

2.9、Lua 元表(Metatable)

3、Lua 协同程序(coroutine)

协同程序与线程非常类似,拥有独立的堆栈,和独立的局部变量,独立的指令和指针,又共享全局变量,协同程序可以理解为一种特殊的线程,可以暂停和恢复其执行,从而允许非抢占式的多任务处理。

同程序由 coroutine 模块提供支持。
使用协同程序,你可以在函数中使用 coroutine.create 创建一个新的协同程序对象,并使用 coroutine.resume 启动它的执行。协同程序可以通过调用 coroutine.yield 来主动暂停自己的执行,并将控制权交还给调用者。

function foo()
    print("协同程序foo开始执行")
    local value = coroutine.yield("让出foo的执行")
    print("协同程序 foo 恢复执行,传入的值为: " .. tostring(value))
    print("协同程序 foo 结束执行")
    return 1
end

-- 创建协同程序
local co = coroutine.create(foo)

-- 启动协同程序
local status,result = coroutine.resume(co)
print(result)

-- 恢复协同程序的执行,并传入一个值
status, result = coroutine.resume(co, 42)
print(result) -- 输出: 协同程序 foo 恢复执行,传入的值为: 42

以上实例中,我们定义了一个名为 foo 的函数作为协同程序。在函数中,我们使用 coroutine.yield 暂停了协同程序的执行,并返回了一个值
。在主程序中,我们使用 coroutine.create 创建了一个协同程序对象,并使用 coroutine.resume 启动了它的执行。
在第一次调用 coroutine.resume 后,协同程序执行到 coroutine.yield 处暂停,并将值返回给主程序。然后,我们再次调用 coroutine.resume,并传入一个值作为协同程序恢复执行时的参数。执行以上代码输出结果为:

在这里插入图片描述

同程序的状态可以通过 coroutine.status 函数获取,通过检查状态可以确定协同程序的执行情况(如运行中、已挂起、已结束等)。

-- 创建了一个新的协同程序对象 co,其中协同程序函数打印传入的参数 i
co = coroutine.create(
    function(i)
        print(i);
    end
)
-- 使用 coroutine.resume 启动协同程序 co 的执行,并传入参数 1。协同程序开始执行,打印输出为 1
coroutine.resume(co, 1) -- 1

-- 通过 coroutine.status 检查协同程序 co 的状态,输出为 dead,表示协同程序已经执行完毕
print(coroutine.status(co)) -- dead
print("----------")

-- 使用 coroutine.wrap 创建了一个协同程序包装器,将协同程序函数转换为一个可直接调用的函数对象
co = coroutine.wrap(
    function(i)
        print(i);
    end
)

co(1)

print("----------")
-- 创建了另一个协同程序对象 co2,其中的协同程序函数通过循环打印数字 1 到 10,在循环到 3 的时候输出当前协同程序的状态和正在运行的线程
co2 = coroutine.create(
    function()
        for i=1,10 do
            print(i)
            if i == 3 then
                print(coroutine.status(co2))    --running
                print(coroutine.running())      --thread:XXXXXX
            end
            coroutine.yield()
        end
    end
)

-- 连续调用 coroutine.resume 启动协同程序 co2 的执行
coroutine.resume(co2) --1
coroutine.resume(co2) --2
coroutine.resume(co2) --3

-- 通过 coroutine.status 检查协同程序 co2 的状态,输出为 suspended,表示协同程序暂停执行
print(coroutine.status(co2))    -- suspended
print(coroutine.running())
print("----------")

在这里插入图片描述
更详细的实例:

function foo (a)
    print("foo 函数输出", a)
    return coroutine.yield(2 * a) -- 返回  2*a 的值
end

co = coroutine.create(function (a , b)
print("第一次协同程序执行输出", a, b) -- co-body 1 10
local r = foo(a + 1)
print("第二次协同程序执行输出", r)
local r, s = coroutine.yield(a + b, a - b) -- a,b的值为第一次调用协同程序时传入
print("第三次协同程序执行输出", r, s)
return b, "结束协同程序" -- b的值为第二次调用协同程序时传入
end)

print("main", coroutine.resume(co, 1, 10)) -- true, 4
print("--分割线----")
print("main", coroutine.resume(co, "r")) -- true 11 -9
print("---分割线---")
print("main", coroutine.resume(co, "x", "y")) -- true 10 end
print("---分割线---")
print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine
print("---分割线---")

生产者消费者模型

-- 生产者消费者模型
-- 1、创建携程
-- 2、调用receive函数,激活协程
-- 2、协程生成一个数据,然后让出协程,将这个数据抛出去
-- 3、receive激活携程这里收到抛出的数据,然后打印出来

local newProductor

function productor()
     local i = 0
     while true do
          i = i + 1
          send(i)     -- 将生产的物品发送给消费者
     end
end

function consumer()
     while true do
          local i = receive()     -- 从生产者那里得到物品
          print(i)
     end
end

function receive()
     local status, value = coroutine.resume(newProductor)
     return value
end

function send(x)
     coroutine.yield(x)     -- x表示需要发送的值,值返回以后,就挂起该协同程序
end

-- 启动程序
newProductor = coroutine.create(productor)
consumer()

线程和协同程序区别

1、线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。
2、在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只有在明确的被要求挂起的时候才会被挂起。

4、文件IO操作

4.1、简单模式

简单模式使用标准的 I/O 或使用一个当前输入文件和一个当前输出文件。

-- 以只读方式打开文件
file = io.open("test.lua", "r")

-- 设置默认输入文件为 test.lua
io.input(file)

-- 输出文件第一行
print(io.read())

-- 关闭打开的文件
io.close(file)

-- 以附加的方式打开只写文件
file = io.open("test.lua", "a")

-- 设置默认输出文件为 test.lua
io.output(file)

-- 在文件最后一行添加 Lua 注释
io.write("--  test.lua 文件末尾注释")

-- 关闭打开的文件
io.close(file)

在这里插入图片描述

4.2、完全模式

通常我们需要在同一时间处理多个文件。我们需要使用 file:function_name 来代替 io.function_name 方法。以下实例演示了如何同时处理同一个文件

-- 以只读方式打开文件
file = io.open("test.lua", "r")

-- 输出文件第一行
print(file:read())

-- 关闭打开的文件
file:close()

-- 以附加的方式打开只写文件
file = io.open("test.lua", "a")

-- 在文件最后一行添加 Lua 注释
file:write("--test")

-- 关闭打开的文件
file:close()

5、错误处理

我们可以使用两个函数:assert 和 error 来处理错误。实例如下:

local function add(a,b)
   assert(type(a) == "number", "a 不是一个数字")
   assert(type(b) == "number", "b 不是一个数字")
   return a+b
end
add(10)

error函数

error (message [, level])

功能:终止正在执行的函数,并返回message的内容作为错误信息(error函数永远都不会返回)
通常情况下,error会附加一些错误位置的信息到message头部。

Level参数指示获得错误的位置:
Level=1[默认]:为调用error位置(文件+行号)
Level=2:指出哪个调用error的函数的函数
Level=0:不添加错误位置信息

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

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

相关文章

软考-访问控制技术原理与应用

本文为作者学习文章&#xff0c;按作者习惯写成&#xff0c;如有错误或需要追加内容请留言&#xff08;不喜勿喷&#xff09; 本文为追加文章&#xff0c;后期慢慢追加 by 2023年10月 访问控制概念 访问控制是计算机安全的一个重要组成部分&#xff0c;用于控制用户或程序如…

Linux | gdb的基本使用

目录 前言 一、调试文件的生成 二、调试指令 1、选择调试文件 2、查看代码 3、运行代码 4、断点 5、打印与常显示 6、其他 总结 前言 前面我们学习了如何使用gcc/g来进行对代码进行编译&#xff0c;本章我们将使用gdb来对代码进行调试&#xff0c;学习本章的前提是有…

实验室用超声波清洗机哪家好

随着超声波清洗机在实验室得到广泛应用&#xff0c;超声波清洗机厂家也随之增多&#xff0c;品牌、型号更是数不胜数&#xff0c;价格相差也是十分悬殊。那么面对纷繁复杂的实验室超声波清洗机市场&#xff0c;实验室用超声波清洗机哪家好&#xff1f;小编推荐国内知名超声波清…

《动手学深度学习 Pytorch版》 9.3 深度循环神经网络

将多层循环神经网络堆叠在一起&#xff0c;通过对几个简单层的组合&#xff0c;产生一个灵活的机制。其中的数据可能与不同层的堆叠有关。 9.3.1 函数依赖关系 将深度架构中的函数依赖关系形式化&#xff0c;第 l l l 个隐藏层的隐状态表达式为&#xff1a; H t ( l ) ϕ l …

用宝塔部署静态html页面

云服务器安装宝塔面板搭建LNMP环境&#xff0c;可以看另一文零基础搭建个人网站详细流程。 本文主要介绍用宝塔部署静态页面&#xff0c;比较简单&#xff0c;以部署一个用户协议为例。 首先&#xff0c;去“网站”中“添加站点”。有域名用域名&#xff0c;没域名用IP。 然后…

NSSCTF做题(10)

叫10好听一点&#xff0c;就是补9的 第7页的内容 [SWPUCTF 2022 新生赛]ez_sql get传参说是不安全&#xff0c;那就只能用post了 有回显了&#xff0c;两个假的flag 发现万能密码 1 or 11#变成了 11# 11# 1 11#1# 11# 11# 发现or和空格都无了&#xff0c;union也过滤 …

零基础Linux_19(进程信号)产生信号+Core_Dump+保存信号

目录 1. 信号前期知识 1.1 生活中的信号 1.2 Linux中的信号 1.3 信号概念 1.4 信号处理方法的注册 2. 产生信号 2.1 通过终端按键产生信号 2.2 调用系统调用向进程发信号 2.3 软件条件产生信号 2.4 硬件异常产生信号 3. 核心转储Core Dump 4. 保存信号 4.1 信号在…

day08_面向对象_封装_继承_this_super_访问修饰符

今日内容 1.作业 2.封装 3.继承 4.this和super 5.访问修饰符 零、复习 成员变量和局部变量(画表格) this的作用 this是当前对象,当前方法的调用者this可以调用属性和方法this.属性, this.方法名(),this() 构造方法的作用和语法特征 作用: 创建对象,属性初始化特征: 没有返回值,…

数据结构和算法(13):优先级队列

概述 按照事先约定的优先级&#xff0c;可以始终高效查找并访问优先级最高数据项的数据结构&#xff0c;也统称作优先级队列 优先级队列将操作对象限定于当前的全局极值者。 根据数据对象之间相对优先级对其进行访问的方式&#xff0c;与此前的访问方式有着本质区别&#xf…

PostgreSQL与MySQL数据库对比:适用场景和选择指南

数据库是现代应用程序的基石之一&#xff0c;而在选择合适的数据库管理系统&#xff08;DBMS&#xff09;时&#xff0c;开发者常常会面临着许多选择。在这方面&#xff0c;PostgreSQL和MySQL是两个备受瞩目的选项。本文将深入研究这两者之间的异同&#xff0c;并为您提供适用场…

疯狂星期四的营销策略是什么?如何复制?

你知道疯狂星期四吗&#xff1f;它的策略是什么&#xff1f;如何对标它写一个类似的方案呢&#xff1f; 1、消费者心理 KFC疯狂星期四的核心目标消费者是对价格敏感的年轻人和家庭消费者。他们寻求物有所值的美食体验&#xff0c;希望在合理的价格范围内享受到美味的食物。通过…

Unity之ShaderGraph如何实现UV抖动

前言 今天我们通过噪波图来实现一个UV抖动的效果。 如下图所示&#xff1a; 关键节点 Time&#xff1a;提供对着色器中各种时间参数的访问 UV&#xff1a;提供对网格顶点或片段的UV坐标的访问。可以使用通道下拉参数选择输出值的坐标通道。 SimpleNoise&#xff1a;根据…

论文导读 | 支持事务与图分析的图存储系统

事务系统保证了系统的数据一致性&#xff0c;确保事务更新的原子性或是不同事务之间的数据隔离性等在多线程并发环境下所必不可少的ACID特性。而在今天快速变化的商业环境下&#xff0c;诸如物流和供应链&#xff0c;金融风控和欺诈检测等场景都需要图分析系统提供对数据动态更…

Node.js在Python中的应用实例解析

随着互联网的发展&#xff0c;数据爬取成为了获取信息的重要手段。本文将以豆瓣网为案例&#xff0c;通过技术问答的方式&#xff0c;介绍如何使用Node.js在Python中实现数据爬取&#xff0c;并提供详细的实现代码过程。 Node.js是一个基于Chrome V8引擎的JavaScript运行时环境…

SEAL:RLWE-BFV 开源算法库

参考文献&#xff1a; GitHub - microsoft/SEAL: Microsoft SEAL is an easy-to-use and powerful homomorphic encryption library.[HS13] Halevi S, Shoup V. Design and implementation of a homomorphic-encryption library[J]. IBM Research (Manuscript), 2013, 6(12-15…

UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)

在UML类图中&#xff0c;常见的有以下几种关系: 泛化&#xff08;Generalization&#xff09;, 实现&#xff08;Realization&#xff09;&#xff0c;关联&#xff08;Association)&#xff0c;聚合&#xff08;Aggregation&#xff09;&#xff0c;组合(Composition)&#x…

【python零基础入门学习】python进阶篇之OOP - 面向对象的程序设计

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

MS5248数模转换器可pin对pin兼容AD5648

MS5228/5248/5268 是一款 12/14/16bit 八通道输出的电压型 DAC&#xff0c;内部集成上电复位电路、可选内部基准、接口采用四线串口模式&#xff0c;最高工作频率可以到 40MHz&#xff0c;可以兼容 SPI、QSPI、DSP 接口和 Microwire 串口。可pin对pin兼容AD5648。输出接到一个 …

潮玩IP助力环境保护,泡泡玛特发布行业首款碳中和产品

在今年的2023上海PTS国际潮流玩具展上&#xff0c;泡泡玛特正式发布了首款“碳中和”潮玩产品DIMOO X蒙新河狸手办&#xff08;下简称DIMOO河狸&#xff09;&#xff0c;通过环保主题与流行文化的联合&#xff0c;让年轻人知道野生动物保护有多种方式&#xff0c;同时以创新的设…

Crypto(3)NewStarCTF 2023 公开赛道 WEEK2|Crypto-不止一个pi

题目代码 from flag import flag from Crypto.Util.number import * import gmpy2 p getPrime(1024) #这行生成一个大约1024位长度的随机素数&#xff0c;并将其赋给变量p。 q getPrime(1024) #类似地&#xff0c;这行生成另一个大约1024位长度的随机素数&#xff0c;并将其…