求一段监视队友技能插件的LUA,N

51CTO旗下网站
8月编程语言排行榜:以总统为名的语言新贵Lua
8月4日,Tiobe公布了最新的8月编程语言排行榜,和7月榜单相比,最大变动就数微软的F#了,F#首次进入TOP20。1至10名中,PHP重返第4,C#则到了第5,其他不变。本期51CTO编程语言排行榜便以Lua语言为主题,介绍这款以巴西总统的名字命名的移动开发语言新贵。
作者:立方来源:| 14:22
8月4日,Tiobe公布了最新的8月编程语言排行榜,和相比,最大变动就数微软的F#了,首次进入TOP20。1至10名中,PHP重返第4,C#则到了第5,其他不变。不过看看最近人气上升的F# ,就没有什么好奇怪的了。作为一种不错的程序设计语言,微软最新的Visual Studio 2010中也包含了F#。
下面是前20名的编程语言排行
2011年6月、7月的Tiobe编程语言排行榜都介绍了移动开发语言Lua,其中以年度语言预测为主题,直言Lua是2011年度唯一有机会挑战的语言。但是Lua到底是什么语言呢?本期51CTO编程语言排行榜便以为主题,介绍这款以巴西总统的名字命名的移动开发语言新贵。51CTO推荐专题:
(图)Lua语言
Lua是一个被设计成用于扩展C/C++编程的轻量级脚本语言,它的目标是成为一个很容易嵌入其它语言中使用的语言。Lua让C/C++编写的代码调用Lua脚本,同时C/C++函数也能够在Lua脚本中调用。与C/C++代码的交互性,让Lua在应用程序开发中有着广泛的应用基础。很多应用程序使用Lua作为自己的嵌入式脚本语言,以此来实现可配置性、可扩展性。
Lua名字的由来
小巧的Lua语言来自于巴西里约热内卢天主教大学的实验性项目。当初巴西里约热内卢天主教大学的师生为什么要给这款语言起名为&Lua&,很大程度上是向巴西著名政治家、前任总统路易斯&伊纳西奥&卢阿&达席尔瓦致敬。卢阿总统是是巴西历史上学历最低,但是支持率最高的总统,深受人民爱戴,作为巴西国家电子领域最重要的人才培养基地的里约热内卢天主教大学计算机研究生院把他们在计算机世界中最重要成就&Lua&语言与他们总统同名,可见他们对Lua语言给予了多么大的希望。
巴西前总统卢阿
Lua语言在移动开发中的成功
2011年以前中国人对Lua语言的老家里约热内卢可以说是基本不了解,不过一部以小鸟爱情为主题的动画片《里约大冒险》让我们了解了里约热内卢的美丽风光。同样一个小鸟保卫鸟蛋的游戏《愤怒的小鸟》让Lua语言风靡开发者的世界。(51CTO扩展阅读《》、《》)
(图)里约大冒险版《愤怒的小鸟》
像前文所说Lua语法简洁优美,解释器由标准C编写。以快速小巧著称的Lua拥有在目前所有脚本引擎中最快的运行速度,这样的特性让Lua成为用作嵌入式脚本的最佳选择。但是,Lua语言被人们所熟知还要追述到1年前乔布斯的苹果将Lua语言引进iOS平台,直到现在已经有很多iPhone的应用写入到Lua中。而Lua语言凭借其代码几乎能在所有操作系统和移动终端上编译运行的这一特性,不但可以在iOS这一移动平台开发,同样也可以在Android等其他平台上开发。51CTO曾介绍过。有了以后Lua语言不但可以支持iOS,还可以支持Android平台。以上这些原因使Lua语言在Tiobe编程语言排行榜上迅速攀升,成为移动开发领域的新贵。
Lua的技术特点
目前Lua语言的最新版本是5.2 Beta,Lua也能对面向对象编程,函数式编程,数据驱动式编程提供很好的支持。作为一个扩展式语言,Lua没有 &main& 程序的概念:它只能嵌入一个宿主程序中工作,这个宿主程序被称作embedding program或简称为host。宿主程序可以通过调用函数执行一小段Lua代码,可以读写Lua变量,可以注入C函数让Lua代码调用。这些扩展的C函数,可以大大的扩展了Lua可以处理事务的领域,这样就可以订制出各种语言,而它们共享一个统一的句法格式的框架。Lua的官方发布版就包含了一个叫做Lua的简单的宿主程序,它用Lua库提供了一个保证独立的Lua解释器。
写一个最最简单的程序&&Hello World。
print(&Hello&World&)&
假定你把上面这句保存在hello.lua文件中,你在命令行只需要:
prompt&lua&hello.lua&
看到结果了吗?
让我们来看一个稍微复杂点的例子:
--&defines&a&factorial&function &function&fact&(n) &&&&&if&n&==&0&then &&&&&&&&return&1 &&&&&else &&&&&&&&return&n&*&fact(n-1) &&&&&end &end && &print(&enter&a&number:&) &a&=&io.read(&*number&)&&&&&&--&read&a&number &print(fact(a))&
这个例子定义了一个函数,计算输入参数n的阶乘;本例要求用户输入一个数字n,然后打印n的阶乘。
(图)魔兽世界插件中的&Hello World&
很多网站宣传Lua语言作为脚本开发了《魔兽世界》,其实,几乎所有的《魔兽世界》插件都是使用解释性的脚本Lua编写,核心的C++代码只占全部代码中的很小一部分比重。在传统平台上Lua最流行的应用场景是在游戏中作为处理逻辑的脚本,即用来编写游戏的任务脚本,以实现游戏的可配置性和可扩展性。在游戏中Lua脚本的加载不需重启服务器,尽管脚本的运行效率低于编译好的二进制代码,但目前CPU速度已完全能够让Lua脚本迅速解释执行。这也正是包括《魔兽世界》、《战锤40K》、《仙境传说》、《博德之门》和《轩辕剑外传汉之云》在内的众多游戏选择Lua开发插件的原因。
(图)魔兽世界中游戏内插件开发的布局器
想学习Lua语言的朋友还可以到魔兽世界Lua插件的编辑器来试验一下。
下面是本期编程语言排行榜的其他排名数据和趋势走向。
前10名编程语言走势图
20到50名语言排行
Programming Language
Visual Basic .NET
ActionScript
OpenEdge ABL
下面是第50到100的编程语言排名
(Visual) FoxPro, ABC, Algol, APL, Arc, ATLAS, Avenue, Awk, Bash, bc, BETA, BlitzMax, Boo, Bourne shell, CFML, cg, CL (OS/400), Cobra, cT, Dylan, Eiffel, Factor, Groovy, Inform, Io, J, Ladder Logic, MAD, Magic, Maple, Mercury, Monkey, MUMPS, Oberon, Occam, OpenCL, Oz, PILOT, PowerShell, Revolution, S, Scala, Smalltalk, Standard ML, SuperCollider, Tcl, TOM, VBScript, VHDL, X10
不同语言的比例
下面给出了编程语言类别的一年变化趋势
【2011年榜单回顾】
【责任编辑: TEL:(010)】
大家都在看猜你喜欢
热点关注头条头条关注
24H热文一周话题本月最赞
讲师:126563人学习过
讲师:108841人学习过
讲师:208001人学习过
精选博文论坛热帖下载排行
Cisco 640-801
Cisco& Certified Network Associate (CCNA&)
Q&A with explanations
Version 93.0...
订阅51CTO邮刊使用 Lua 编写一个 Nginx 认证模块 - 技术翻译 - 开源中国社区
使用 Lua 编写一个 Nginx 认证模块
【已翻译100%】
英文原文:
推荐于 5年前 (共 9 段, 翻译完成于 09-09)
参与翻译&(3人)&: ,
过去两天里,我解决了一个非常有趣的问题。我用一个nginx服务器作为代理,需要能够向其中添加一个认证层,使其能够使用外部的认证源(比如某个web应用)来进行验证,如果用户在外部认证源有账号,就可以在代理里认证通过。
我考虑了几种解决方案,罗列如下:
用一个简单的Python/Flask模块来做代理和验证。
一个使用subrequests做验证的nginx模块(nginx目前可以做到这一点)
使用Lua编写一个nginxren认证模块
&翻译得不错哦!
很显然,给整个系统添加额外请求将执行的不是很好,因为这将会增加延迟(特别是给每一个页面文件都增加一个请求是很让人烦恼的).这就意味着我们把subrequest模块排除在外了。Python/Flash解决方案好像对nginx支持的也并不好,所以咱也把它排除了。就剩Lua了,当然nginx对原生化支持得不错的。
因为我不想再扩展的服务器上对每一个请求都做认证,所以我决定生成一些令牌,这样人们就可以将它保存起来,并把它呈现给服务器,然后服务器就让请求通过。然而,因为Lua模块没有一种保持状态的方式(我已经发现),所以我们不能将令牌随处存储。当你没有更多的内存时,怎样来验证用户所说的话呢?
&翻译得不错哦!
加密签名的方式可是咱的救星!我们可以拿用户的用户名和过期时间数据来给用户添加签名的cookies,这样就能很容易的验证每个用户是谁了,同时我们就不用令牌了。
在nginx中,我们要做的就是直接在指定位置配置access_by_lua_file /our/file.lua,这样这个指定位置就可以保护我们的脚本了。现在,让我们一起来写代码:
-- Some variable declarations.
local cookie = ngx.var.cookie_MyToken
local hmac = ""
local timestamp = ""
local timestamp_time = 0
-- Check that the cookie exists.
if cookie == nil or cookie:find(":") == nil then
-- Internally rewrite the URL so that we serve
-- /auth/ if there's no cookie.
ngx.exec("/auth/")
-- If there's a cookie, split off the HMAC signature
-- and timestamp.
local divider = cookie:find(":")
hmac = cookie:sub(divider+1)
timestamp = cookie:sub(0, divider-1)
-- Verify that the signature is valid.
if hmac_sha1("some very secret string", timestamp) ~= hmac or tonumber(timestamp) & os.time() then
-- If invalid, send to /auth/ again.
ngx.exec("/auth/")
end 上面的代码可以直接运行。我们用一些明文来签名(这种情况下用的是一个时间戳,当然你可以用任何你想用的),之后我们用密文生成HMAC(哈希信息认证码),然后一个签名就生成了,这样用户就不能篡改为无效信息了。
&翻译得不错哦!
当用户试图载入一个资源的时候,我们会检查cookie里面的签名是否有效,如果是,就通过他的请求。反之,我们会把他们重定向到一个发行口令的服务器,这个服务器会验证并且在没有的情况下给予他们一个签名的口令。
明锐的你可能会发现,上面的代码存在时间上的漏洞。如果你没有发现,别难过。嗯,也许会有点难过。
这里是一段Lua的代码,用来比较两个字符串在恒定时间上的等值关系(因而能够阻止任何时间上的攻击,除非我忽视了什么,这极为可能):
function compare_strings(str1, str2)
-- Constant-time string comparison function.
local same = true
for i = 1, #str1 do
-- If the two strings' lengths are different, sub()
-- will just return nil for the remaining length.
c1 = str1:sub(i,i)
c2 = str2:sub(i,i)
if c1 ~= c2 then
same = false
return same
end 我已经在函数上应用了时间来区分,如我所知,这是一个在恒定时间下的等值字符串。不同长度的字符串会稍稍改变时间,也许是因为子过程sub应用了一个不同的分支而导致的。而且,c1~=c2分支显然不是恒定时间的,但是在实际中,它相当接近恒定,所以于我们的例子不会有影响。我更倾向于使用XOR操作,从而确定两个字符串的XOR结果是否为0, 不过Lua似乎不包括二进制位的XOR操作。如果我在这个判断上有误,对于任何纠正我都很感激。
&翻译得不错哦!
口令发行服务器
现在,我们已经写了一些很棒的口令检查代码,所有需要做的,只是写一个服务器来真正的发行这些口令。我本可以用Python以及Flask来写这个服务器,不过我还是想用Go做一个尝试,因为我是一个计算机语言潮人而且Go看上去“酷”。使用Python大概会快一些,不过我乐意用Go。
这个服务器会弹出一个HTTP基础验证的表单,检查你输入的帐户,如果正确,它会给你一个签名的口令,适合于一个小时的代理服务器访问。这样,你只需要验证外部服务一次,而随后的身份验证的检查将在nginx层面,而且会相当的快。
&翻译得不错哦!
请求处理器
写一个处理器,来弹出一个基本的验证窗体不是很难,但是Go没有完美的文档,所以我必须自己一点点寻猎。其实非常简单,最终,这里就是HTTP基本验证的Go代码:
func handler(w http.ResponseWriter, r *http.Request) {
if username := checkAuth(r); username == "" {
w.Header().Set("WWW-Authenticate", `Basic realm="The kingdom of Stavros"`)
w.WriteHeader(401)
w.Write([]byte("401 Unauthorized\n"))
fmt.Printf("Authenticated user %v.\n", username)
token := getToken()
setTokenCookie(w, token)
fmt.Fprintf(w, "&html&&head&&script&location.reload()&/script&&/head&&/html&")
&翻译得不错哦!
设置口令和cookie
一旦我们验证了一个用户之后,我们需要给他们的口令设置一个cookie。我门只需要做我们用Lua做过的同样的事情,如上,只是更加简单,因为Go在标准库里面就包括一个真加密包。这个代码一样很直接明了,即使没有完全文档化:
func getToken() string {
expiration := int(time.Now().Unix()) + 3600
mac := hmac.New(sha1.New, []byte("some very secret string"))
mac.Write([]byte(fmt.Sprintf("%v", expiration)))
expectedMAC := fmt.Sprintf("%x", mac.Sum(nil))
return fmt.Sprintf("%v:%s", expiration, expectedMAC)
func setTokenCookie(w http.ResponseWriter, token string) {
rawCookie := fmt.Sprintf("MyToken=%s", token)
expire := time.Now().Add(time.Hour)
cookie := http.Cookie{"MyToken",
".example.com",
expire.Format(time.UnixDate),
rawCookie,
[]string{rawCookie}}
http.SetCookie(w, &cookie)
&翻译得不错哦!
尝试把他们放在一起
来完成我们这一大段美妙的组合,我们只需要一个函数,用来检查由用户提供的验证信息,而且我们做到了!这里是我从一些库里面汲取出来的代码,当前它只是检查一个特定的用户名/密码的组合,所以和第三方的服务的集成就做为留给读者的作业吧:
func checkAuth(r *http.Request) string {
s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
if len(s) != 2 || s[0] != "Basic" {
b, err := base64.StdEncoding.DecodeString(s[1])
if err != nil {
pair := strings.SplitN(string(b), ":", 2)
if len(pair) != 2 {
if pair[0] != "username" || pair[1] != "password" {
return pair[0]
&翻译得不错哦!
我到目前对于nginx的Lua模块还是有着相当的喜欢。它允许你在web服务器的请求/响应周期里面做一些简单的操作,而且对于某些操作,比如为代理服务器做验证的检查,是很有意义的。这些事情对于一个不可编程的web服务器,一直很难,因此我们极可能需要写自己的HTTP代理服务。
上面的代码相当的简短,而且优雅,所以我对于上面的所有都感到高兴。我不能确定,这对于响应添加了多少额外的时间,不过,做一个验证是有好处的,我想这将值得去做(而且应该足够快,所以不是一个问题)。
另一个好处就是,你可以仅使用一个在nginxlocationblock里面的单独的directive来开启它,所以没有需要跟踪的配置项。我发现,总体而言,这是一个非常优雅的解决方案,而且我很高兴的了解到nginx可以让我去做这样的事情,可能是将来我需要去做的。
如果你有任何建言或者是反馈,请留下你的评语(特别是如果我把某些地方给弄错了)。
&翻译得不错哦!
我们的翻译工作遵照 ,如果我们的工作有侵犯到您的权益,请及时联系我们
其实国人写有一个功能丰富的Nginx Lua模块——ngx_openresty/lua(在CPU/内存消耗上要比PHP-FPM少得多)使用 content_by_lua 把lua脚本嵌入到Nginx配置里,或者使用 content_by_lua_file 把Lua脚本载入到Nginx配置里.例子:ngx_openresty/lua连接mysql查询并返回数据:https://github.com/agentzh/mysql-driver-benchmark/blob/master/drizzle-lua/conf/nginx.confhttp://openresty.org/cn/index.html
其实国人写有一个功能丰富的Nginx Lua模块——ngx_openresty/lua(在CPU/内存消耗上要比PHP-FPM少得多)使用 content_by_lua 把lua脚本嵌入到Nginx配置里,或者使用 content_by_lua_file 把Lua脚本载入到Nginx配置里.例子:ngx_openresty/lua连接mysql查询并返回数据:https://github.com/agentzh/mysql-driver-benchmark/blob/master/drizzle-lua/conf/nginx.confhttp://openresty.org/cn/index.html+++
其实国人写有一个功能丰富的Nginx Lua模块——ngx_openresty/lua(在CPU/内存消耗上要比PHP-FPM少得多)使用 content_by_lua 把lua脚本嵌入到Nginx配置里,或者使用 content_by_lua_file 把Lua脚本载入到Nginx配置里.例子:ngx_openresty/lua连接mysql查询并返回数据:https://github.com/agentzh/mysql-driver-benchmark/blob/master/drizzle-lua/conf/nginx.confhttp://openresty.org/cn/index.html文中说的时间上的漏洞是啥??我看了半天也看不出来啊
其实国人写有一个功能丰富的Nginx Lua模块——ngx_openresty/lua(在CPU/内存消耗上要比PHP-FPM少得多)使用 content_by_lua 把lua脚本嵌入到Nginx配置里,或者使用 content_by_lua_file 把Lua脚本载入到Nginx配置里.例子:ngx_openresty/lua连接mysql查询并返回数据:https://github.com/agentzh/mysql-driver-benchmark/blob/master/drizzle-lua/conf/nginx.confhttp://openresty.org/cn/index.html引用来自“nvksie”的评论文中说的时间上的漏洞是啥??我看了半天也看不出来啊唉,翻墙看了原文才知道,人家都更新好几版了,代码不一样了,结论也变了,所以为毛大牛们都喜欢看原版啊,这就是原因啊。留着错误都没人改啊,还有一帮乌合之众呐它当宝贝吹捧着。唉。差距啊

我要回帖

更多关于 监视队友技能插件 的文章

 

随机推荐