已知格式求按键精灵卡通农场源代码暴力破解密码的源代码

悬赏一个可以纯暴力破解手机软件的六位数密码的脚本,有偿【按键精灵吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:404,663贴子:
悬赏一个可以纯暴力破解手机软件的六位数密码的脚本,有偿收藏
新朗页游助手支持海量页游,页游辅助完美支持小号多开,微端多平台登陆.精品页游辅助工具,自动日常,自动副本,一键操作,玩页游更省时!
求大神,有意qq
有回报,求大神,要不然这个学期就挂科了
那软件估计是收费的吧
登录百度帐号求按键精灵编密码暴力破解器源代码_百度知道
求按键精灵编密码暴力破解器源代码
rt,密码是3位数字,很有可能是纯数字,确认以后的时间大慨为两秒。基本上是,开始,输入001,回车,等待两秒,弹出提示,密码不正确,点回车,再tab,输入002,这样循环。如果正确会...
rt,密码是3位数字,很有可能是纯数字,确认以后的时间大慨为两秒。基本上是,开始,输入001,回车,等待两秒,弹出提示,密码不正确,点回车,再tab,输入002,这样循环。如果正确会自动关闭软件,这时软件停止。其他软件业可以,只要实现此功能
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
采纳数:15
获赞数:27
自动关闭我无能为力如果不自动关闭的话:Dim ADim BDim CA = 0B = 0C = 1Rem T1SayString ASayString BSayString CKeyPress &Enter&, 1Delay 2000KeyPress &Enter&, 1KeyPress &Tab&, 1C = C + 1If C = 10 ThenC = 0B = B + 1End IfIf B = 10 Then B = 0A = A + 1End IfIf A = 10 Then EndScriptEnd If Goto T1
东京热小蛋
东京热小蛋
获赞数:12
只考虑实现这个功能的话,很简单啊。如果你有按键基础往下看,如果想要源码,对不起除非手上刚好有,没人会为200分帮你写,下面看懂了,自己写就行了。首先利用ASCII码,这样就得出了键盘上面所有字符对应的数字。数字可以利用数学公式进行+1,-1计算。做一个循环。三个组合比较简单,3个循环,for{for{for{}}},就是这个样子。成功就返回ture,break跳出循环。原理很简单,学个基础就可以写了。希望能帮到你。
为你推荐:
其他类似问题
您可能关注的内容
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。可以破解常见的几种路由器的密码,让你畅游Wifi无线网络!利用暴力破解方法,常见密码探测法,默认密码探测法等多种方法,还可以自定制密码字典!本应用不保证一定能够破解密码,可以多尝试几次
手机扫描二维码下载
大家都在玩
大小:2.19MB
【产品介绍】WiFi密码破解器,专业的密码破解工具, 智能高效快速破解,云端存储...
大小:256KB
wifi密码破解器是一款破解wifi密码的系统工具,可破解无线路由密钥几种常见的密码...
大小:880.81KB
WIFI密码破解查看器应用简介WIFI密码破解查看器可以查看手机里隐藏的WIFI密码,我...
大小:1.7MB
极速wifi密码破解器是一款非常实用的无线路由器相关密钥破解工具。本应用根据wifi...
大小:1.83MB
WiFi密码破解器,新春助力,破解WiFi无线网络的密钥,欢快畅游网络世界,跟2G网说...
大小:2.74MB
WiFi密码破解器,是一款免费的WiFi无线网络相关密码破解工具,是真正能够破解WiF密...
大小:1.09MB
【小编强力推荐】wifi密码破解,一款真实可用的wifi密码破解神器。你还在为到处都...
大小:5.31MB
【小编强力推荐】wifi密码破解,一款真实可用的wifi密码破解神器。你还在为到处都...
大小:5.31MB
【小编强力推荐】wifi密码破解,一款真实可用的wifi密码破解神器。你还在为到处都...
大小:2.05MB
WiFi密码破解器是一款多功能的wifi管理工具。创造性的把wifi热点连接,wifi本地密...
大小:1.72MB
wifi密码破解器是一款手机必备的热点管理工具,主要用于查看当前设备曾经连接过的...
大小:3.08MB
WiFi密码破解器,是一款免费的WiFi无线网络相关密码破解工具,是真正能够破解WiF密...
大小:2.89MB
WiFi密码破解器,是一款免费的WiFi无线网络相关密码破解工具,是真正能够破解WiF密...
大小:2.89MB
WiFi密码破解器,是一款免费的WiFi无线网络相关密码破解工具,是真正能够破解WiF密...
WiFi密码破解器,是一款免费的WiFi无线网络相关密码破解工具,是真正能够破解WiF密...
WiFi密码破解器,是一款免费的WiFi无线网络相关密码破解工具,是真正能够破解WiF密...
WiFi密码破解器,是一款免费的WiFi无线网络相关密码破解工具,是真正能够破解WiF密...
大小:2.05MB
WiFi密码破解器,专业的密码破解工具, 智能高效快速破解,云端存储上亿免费WiFi...
大小:1.51MB
wifi密码破解查看器是一款多功能的wifi管理工具。创造性的把wifi热点连接,wifi本...
大小:1.86MB
专业破解WIFI密码查看器可以查看手机里隐藏的WIFI密码,我们的手机WIFI密码本身是...
大家都在玩
热门安卓应用
WiFi万能钥匙
百度输入法
搜狗输入法
其他用户正在浏览
WiFi万能钥匙
百度输入法
搜狗输入法404 Not Found
404 Not Found&p&谢邀。&/p&&p&计算机中有两种随机数。一种叫伪随机数,一种叫真随机数。&/p&&p&顾名思义,伪随机数是假的随机数。他实际上是用一套算法计算出来的看似随机数的序列。算法接收一个初始值(通常被称为种子),然后维护一个内部状态,你每请求一次随机数,就会计算一次,多次请求得到的数字序列看起来很像一个随机数列。但如果你给出固定的种子,计算出来的序列就会一样。&/p&&p&伪随机数有各种不同的算法,通常用来衡量算法质量的是计算速度,出来的数字序列分布是否均匀,是否有足够的随机性,是否有明显的规律(有的话就是缺陷),是否有周期(没有的比有的好),周期有多长(越长越好),反推难度(依照已知的输出能否反推内部状态从而预测之后的输出,越难越好)。&/p&&p&之所以有伪随机数,因为&b&算法是不可能给出真正的随机数的&/b&。算法只能依确定的逻辑,然后根据输入数据给出确定的结果。&/p&&p&&b&绝大多数语言内置的标准库中的随机数相关设施,都是伪随机数&/b&。&/p&&p&真随机数,也就是顾名思义的,真正的不可预测的随机数,&b&靠的不是某种算法,而是某种无法预测的物理过程,因此基本都需要硬件支持&/b&。&/p&&p&新款Intel CPU(酷睿3xxx系列以及后续产品)上有一个硬件随机数发生器,靠的是收集CPU中的电路噪音。&/p&&p&一些硬件随机数卡,靠的是根据天线收集环境中的电磁波噪音。&/p&&p&还有一些硬件甚至依靠检测内部的放射性元素衰变计数来产生随机数。&/p&&p&Linux内核有一个特殊的随机数设备/dev/random,靠的是搜集系统内所有IO信号(比如你移动鼠标的轨迹,敲击键盘的时间间隔)来填充一个内部的随机数生成池。&/p&&p&一般来说,真随机数大多用在对随机性要求很高的场合。比如数字证书密钥的生成等。因为真随机数生成的成本比伪随机数高得多。其他场合,现代的伪随机数算法已经足够满足要求。&/p&&p&=================================================&/p&&p&补充几点:&/p&&p&真随机数生成成本高,意思基本就是生成的速度慢,难以用廉价的手段加快生成速度。&/p&&p&伪随机数是算法生成的,本身就很快,而且你用更快的CPU,并行更多个线程,还能大幅度加快速度。&/p&&p&而真随机数靠的是将随机的物理过程数字化,将物理过程加速可就难得多了。而你要使用多个物理设备一起运行的话,这成本可就……&/p&&p&即使是看起来很快的Intel CPU上面的那个随机数发生器,调用的时候也需要少则400多,多则将近1500个时钟周期,这比一般的伪随机数算法要慢一到两个数量级。&/p&&p&Linux内核的那个/dev/random设备有可能超慢。这个设备会估算现在搜集的信息熵的数量,也就是“随机程度”,当你用过一次以后,设备会认为信息熵已经清空,在收集足够的系统噪声之间,尝试使用该设备时会阻塞。这种阻塞可以很长,长到能让人感觉到。&/p&&a href=&//link.zhihu.com/?target=https%3A//my.oschina.net/wangnian/blog/687914& data-draft-node=&block& data-draft-type=&link-card& data-image=&https://pic1.zhimg.com/v2-7b63eb71c443dfe85cced4_180x120.jpg& data-image-width=&2004& data-image-height=&814& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Tomcat启动时SecureRandom超级慢的问题 - 王念博客 - 开源中国&/a&&p&将当前时间当成随机数种子是一种常用办法,但是随机性并不算高。因为当前时间里不可预测的内容只有一小部分。&/p&&p&将真随机数和伪随机算法对接是可行的。而且实践中也经常使用。因为真随机数生成成本很高,所以将一个真随机数当种子,然后使用伪随机数流,通常来说效果已经很不错了。&/p&
谢邀。计算机中有两种随机数。一种叫伪随机数,一种叫真随机数。顾名思义,伪随机数是假的随机数。他实际上是用一套算法计算出来的看似随机数的序列。算法接收一个初始值(通常被称为种子),然后维护一个内部状态,你每请求一次随机数,就会计算一次,多次…
&figure&&img src=&https://pic1.zhimg.com/v2-224f05ab136eeaddc95d91e36d8ae550_b.jpg& data-rawwidth=&1426& data-rawheight=&538& class=&origin_image zh-lightbox-thumb& width=&1426& data-original=&https://pic1.zhimg.com/v2-224f05ab136eeaddc95d91e36d8ae550_r.jpg&&&/figure&&p&注:建议使用 Python 3,本文所有代码虽然可以使用 Python2 运行,但图像实现有些缺陷&/p&&p&&br&&/p&&p&使用 Python 可以用简单的逻辑画出一些的空间填充曲线,比如下面 Hilbert 曲线、Dragon 曲线 以及 Gosper 曲线,这些曲线都可以『一笔画』画出&/p&&figure&&img src=&https://pic1.zhimg.com/v2-c8b3fcf85ac_b.jpg& data-size=&normal& data-rawwidth=&1116& data-rawheight=&290& class=&origin_image zh-lightbox-thumb& width=&1116& data-original=&https://pic1.zhimg.com/v2-c8b3fcf85ac_r.jpg&&&figcaption&Hilbert 曲线,园林艺术~&/figcaption&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-56f5284dad1dbddbd1c84a_b.jpg& data-size=&normal& data-rawwidth=&1090& data-rawheight=&340& class=&origin_image zh-lightbox-thumb& width=&1090& data-original=&https://pic4.zhimg.com/v2-56f5284dad1dbddbd1c84a_r.jpg&&&figcaption&Dragon 曲线,名字源自像一个龙;不确定是恐龙还是西方龙&/figcaption&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-9b41e04ede96a9fac08d1ba4_b.jpg& data-size=&normal& data-rawwidth=&1052& data-rawheight=&308& class=&origin_image zh-lightbox-thumb& width=&1052& data-original=&https://pic1.zhimg.com/v2-9b41e04ede96a9fac08d1ba4_r.jpg&&&figcaption&Gosper 曲线&/figcaption&&/figure&&p&上面 3 种曲线的点生成算法都非常简单,不需要 import 任何库&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# Hilbert 曲线
def _hilbert(direction, rotation, order):
if order == 0:
direction += rotation
_hilbert(direction, -rotation, order - 1)
step(direction)
direction -= rotation
_hilbert(direction, rotation, order - 1)
step(direction)
_hilbert(direction, rotation, order - 1)
direction -= rotation
step(direction)
_hilbert(direction, -rotation, order - 1)
def step(direction):
next = {0: (1, 0), 1: (0, 1), 2: (-1, 0), 3: (0, -1)}[direction & 0x3]
global x, y
x.append(x[-1] + next[0])
y.append(y[-1] + next[1])
def hilbert(order):
global x, y
_hilbert(0, 1, order)
return (x, y)
&/code&&/pre&&/div&&p&当然,要将其画出来,需要额外的库。这里使用的是 Matplotlib,安装见&/p&&a href=&https://link.zhihu.com/?target=https%3A//matplotlib.org/& data-draft-node=&block& data-draft-type=&link-card& data-image=&https://pic3.zhimg.com/v2-7bddf9fa309bac9f7cdf846_180x120.jpg& data-image-width=&542& data-image-height=&130& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Installation - Matplotlib 2.2.2 documentation&/a&&p&然后简单的使用方式是&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&import matplotlib.pyplot as plt
x, y = hilbert(4);plt.plot(x, y); plt.show()
&/code&&/pre&&/div&&figure&&img src=&https://pic1.zhimg.com/v2-79ea5cce6e63e14ad78ef_b.jpg& data-caption=&& data-size=&small& data-rawwidth=&1150& data-rawheight=&882& class=&origin_image zh-lightbox-thumb& width=&1150& data-original=&https://pic1.zhimg.com/v2-79ea5cce6e63e14ad78ef_r.jpg&&&/figure&&p&稍微复杂点的使用方式&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 4)
for i in range(4):
sub = ax[i]
sub.axis(&off&)
sub.set_aspect(&equal&)
x, y = hilbert(i + 1)
sub.plot(x, y)
plt.show()
&/code&&/pre&&/div&&figure&&img src=&https://pic1.zhimg.com/v2-b0c08f4e5704f1bde941ed370e0eba84_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1058& data-rawheight=&286& class=&origin_image zh-lightbox-thumb& width=&1058& data-original=&https://pic1.zhimg.com/v2-b0c08f4e5704f1bde941ed370e0eba84_r.jpg&&&/figure&&p&Dragon 曲线点生成逻辑&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&def _dragon_A(direction, order):
if order == 0:
return direction
direction = _dragon_A(direction, order - 1)
direction += 1
direction = _dragon_B(direction, order - 1)
step(direction)
direction += 1
return direction
def _dragon_B(direction, order):
if order == 0:
return direction
direction -= 1
step(direction)
direction = _dragon_A(direction, order - 1)
direction -= 1
direction = _dragon_B(direction, order - 1)
return direction
def step(direction):
next = {0: (1, 0), 1: (0, 1), 2: (-1, 0), 3: (0, -1)}[direction & 0x3]
global x, y
x.append(x[-1] + next[0])
y.append(y[-1] + next[1])
def dragon(order):
global x, y
direction = 0
step(direction)
_dragon_A(0, order)
return (x, y)
&/code&&/pre&&/div&&p&&br&&/p&&p&Gosper 曲线点生成逻辑&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&def _gosper_A(direction, order):
if order == 0:
step(direction)
_gosper_A(direction, order - 1)
direction -= 1
_gosper_B(direction, order - 1)
direction -= 2
_gosper_B(direction, order - 1)
direction += 1
_gosper_A(direction, order - 1)
direction += 2
_gosper_A(direction, order - 1)
_gosper_A(direction, order - 1)
direction += 1
_gosper_B(direction, order - 1)
def _gosper_B(direction, order):
if order == 0:
step(direction)
direction += 1
_gosper_A(direction, order - 1)
direction -= 1
_gosper_B(direction, order - 1)
_gosper_B(direction, order - 1)
direction -= 2
_gosper_B(direction, order - 1)
direction -= 1
_gosper_A(direction, order - 1)
direction += 2
_gosper_A(direction, order - 1)
direction += 1
_gosper_B(direction, order - 1)
cos30 = 3.0 ** 0.5 / 2.0
sin30 = 0.5
nexts = {0: (cos30, sin30), 1: (0, 1), 2: (-cos30, sin30), 3: (-cos30, -sin30), 4: (0, -1), 5: (cos30, -sin30)}
def step(direction):
next = nexts[direction % 6]
global x, y
x.append(x[-1] + next[0])
y.append(y[-1] + next[1])
def gosper(order):
global x, y
_gosper_A(0, order)
return (x, y)
&/code&&/pre&&/div&&p&&br&&/p&&p&上面 3 种曲线的点生成算法,虽然简单,但是每一次对于一个新的曲线或者图形都要新写的一段逻辑,还是略显麻烦。实际上有一个通用的规则来描述各种曲线和图形,然后对于这个通用规则可以写一个解释器,就可以很容易的描述一个新的曲线和图形&/p&&p&&br&&/p&&p&&b&L-system&/b&&/p&&p&L-system,全称 Lindenmayer system,是一位植物学家开发的。在本文中会实现一个简单的 L-system 解释器,因为只使用部分功能,所以这个解释器只是 L-system 的一个子集&/p&&figure&&img src=&https://pic1.zhimg.com/v2-f2dd58a8bef_b.jpg& data-size=&small& data-rawwidth=&1148& data-rawheight=&858& class=&origin_image zh-lightbox-thumb& width=&1148& data-original=&https://pic1.zhimg.com/v2-f2dd58a8bef_r.jpg&&&figcaption&根据 L-system 规则生成的植物图&/figcaption&&/figure&&p&L-system 可以使用一个非常形式化的 三元组 &img src=&https://www.zhihu.com/equation?tex=%28V%2C+%5Comega%2C+P%29& alt=&(V, \omega, P)& eeimg=&1&& 来定义。但估计大家应该不会对此有兴趣,如果真有兴趣的话可以参考&/p&&a href=&https://link.zhihu.com/?target=https%3A//baike.baidu.com/item/L%25E7%25B3%25BB%25E7%25BB%259F/Ffr%3Daladdin& data-draft-node=&block& data-draft-type=&link-card& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&L系统_百度百科&/a&&a href=&https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/L-system& data-draft-node=&block& data-draft-type=&link-card& data-image=&https://pic1.zhimg.com/v2-1d4eecbd31b2b9cd57d9a280_180x120.jpg& data-image-width=&800& data-image-height=&574& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&L-system - Wikipedia&/a&&p&下面我们直接通过示例,来解释 L-system&/p&&p&&br&&/p&&p&Gosper 曲线的 L-system&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&{
&start&: &A&,
&rules&: {&A&: &A-B--B+A++AA+B-&, &B&: &+A-BB--B-A++A+B&}
&iterator: 2
&/code&&/pre&&/div&&p&使用一个字符串来代表 Gosper 曲线的生成过程。根据 start 知道 A 是起始字符串 str,根据 rules 中的替换规则,不断的把 str 中的 A 和 B 替换成箭头右边的字符串,替换次数为预先指定的迭代次数 iterator&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&第 0 次,起始 A
第 1 次 A =& A-B--B+A++AA+B-
第 2 次 A-B--B+A++AA+B- =& A-B--B+A++AA+B--+A-BB--B-A++A+B--+A-BB--B-A++A+B+A-B--B+A++AA+B-++A-B--B+A++AA+B-A-B--B+A++AA+B-++A-BB--B-A++A+B-
&/code&&/pre&&/div&&p&替换完成后,最后赋予字符串几何意义,代表如下意思 —— 任意设定起点和方向,从左到右扫描字符串,遇到 A / B 就前进一格,遇到 + 向左旋转 60°,遇到 - 向右旋转 60°。如此就可以得到一个 Gosper 曲线&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&{
&rotate&: 60,
&actions&: {&+&: &left&, &-&: &right&, &A&: &forward&, &B&: &forward&}
&/code&&/pre&&/div&&p&&br&&/p&&p&下面我们来实现一个简单的 L-system 解释器,并验证如上的 Gosper 曲线规则&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&def replacement(str, rules, order):
for i in range(order):
for s in str:
if s in rules:
dst += rules[s]
return str
def interpretation(str, actions, rotate, angle, x, y):
import math
point_x = [x,]
point_y = [y,]
for s in str:
if s not in actions:
if actions[s] == &left&:
angle -= rotate
elif actions[s] == &right&:
angle += rotate
elif actions[s] == &forward&:
r = angle / 180.0 * math.pi
point_x.append(point_x[-1] + math.cos(r))
point_y.append(point_y[-1] + math.sin(r))
return point_x, point_y
&/code&&/pre&&/div&&p&验证&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# Gosper 曲线
grammer = {
&start&: &A&,
&rules&: {&A&: &A-B--B+A++AA+B-&, &B&: &+A-BB--B-A++A+B&},
geometry = {
&rotate&: 60,
&actions&: {&+&: &left&, &-&: &right&, &A&: &forward&, &B&: &forward&}
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 4)
for i in range(4):
str = replacement(grammer[&start&], grammer[&rules&], i + 1)
x, y = interpretation(str, geometry[&actions&], geometry[&rotate&], 30, 0, 0)
sub = ax[i]
sub.axis(&off&)
sub.set_aspect(&equal&)
sub.plot(x, y)
plt.show()
&/code&&/pre&&/div&&figure&&img src=&https://pic3.zhimg.com/v2-d88a0808afb3a67b02cf6e_b.jpg& data-size=&normal& data-rawwidth=&1328& data-rawheight=&342& class=&origin_image zh-lightbox-thumb& width=&1328& data-original=&https://pic3.zhimg.com/v2-d88a0808afb3a67b02cf6e_r.jpg&&&figcaption&Gosper 曲线 迭代次数 1 / 2 / 3 / 4&/figcaption&&/figure&&p&有了这个最基本的 L-system 解释器,我们再来画别的曲线就很容易了&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# Sierpinski arrowhead 曲线
grammer = {
&start&: &A&,
&rules&: {&A&: &B-A-B&, &B&: &A+B+A&},
geometry = {
&rotate&: 60,
&actions&: {&+&: &left&, &-&: &right&, &A&: &forward&, &B&: &forward&}
&/code&&/pre&&/div&&figure&&img src=&https://pic2.zhimg.com/v2-dcde41568edcf_b.jpg& data-size=&normal& data-rawwidth=&1336& data-rawheight=&416& class=&origin_image zh-lightbox-thumb& width=&1336& data-original=&https://pic2.zhimg.com/v2-dcde41568edcf_r.jpg&&&figcaption&Sierpinski arrowhead 曲线 迭代次数 2 / 4 / 6 / 8&/figcaption&&/figure&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# Sierpinski triangle
grammer = {
&start&: &F-G-G&,
&rules&: {&F&: &F-G+F+G-F&, &G&: &GG&},
geometry = {
&rotate&: 120,
&actions&: {&+&: &left&, &-&: &right&, &F&: &forward&, &G&: &forward&}
&/code&&/pre&&/div&&figure&&img src=&https://pic4.zhimg.com/v2-e6f2a5c9d9c3b348efdb536a89d6ce48_b.jpg& data-size=&normal& data-rawwidth=&1282& data-rawheight=&482& class=&origin_image zh-lightbox-thumb& width=&1282& data-original=&https://pic4.zhimg.com/v2-e6f2a5c9d9c3b348efdb536a89d6ce48_r.jpg&&&figcaption&Sierpinski triangle 迭代次数 2 / 4 / 6&/figcaption&&/figure&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# Koch snowflake
grammer = {
&start&: &F&,
&rules&: {&F&: &F+F--F+F&},
geometry = {
&rotate&: 60,
&actions&: {&+&: &left&, &-&: &right&, &F&: &forward&}
&/code&&/pre&&/div&&figure&&img src=&https://pic2.zhimg.com/v2-575533cab9ee7fdba9bd2cf_b.jpg& data-size=&normal& data-rawwidth=&1348& data-rawheight=&188& class=&origin_image zh-lightbox-thumb& width=&1348& data-original=&https://pic2.zhimg.com/v2-575533cab9ee7fdba9bd2cf_r.jpg&&&figcaption&Koch snowflake 迭代次数 1 / 2 / 3 / 4&/figcaption&&/figure&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# Hilbert 曲线
grammer = {
&start&: &A&,
&rules&: {&A&: &-BF+AFA+FB-&, &B&:&+AF-BFB-FA+&},
geometry = {
&rotate&: 90,
&actions&: {&+&: &left&, &-&: &right&, &F&: &forward&}
&/code&&/pre&&/div&&figure&&img src=&https://pic3.zhimg.com/v2-57fb2c053b7b4acb61be_b.jpg& data-size=&normal& data-rawwidth=&1340& data-rawheight=&380& class=&origin_image zh-lightbox-thumb& width=&1340& data-original=&https://pic3.zhimg.com/v2-57fb2c053b7b4acb61be_r.jpg&&&figcaption&Hilbert 曲线 迭代次数 1 / 2 / 3 / 4&/figcaption&&/figure&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# Dragon 曲线
grammer = {
&start&: &FX&,
&rules&: {&X&: &X+YF+&, &Y&: &-FX-Y&},
geometry = {
&rotate&: 90,
&actions&: {&+&: &left&, &-&: &right&, &F&: &forward&}
&/code&&/pre&&/div&&figure&&img src=&https://pic3.zhimg.com/v2-91eede12a47b003ce8668_b.jpg& data-size=&normal& data-rawwidth=&1342& data-rawheight=&368& class=&origin_image zh-lightbox-thumb& width=&1342& data-original=&https://pic3.zhimg.com/v2-91eede12a47b003ce8668_r.jpg&&&figcaption&Dragon 曲线 迭代次数 1 / 4 / 9 / 16&/figcaption&&/figure&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# 不知名的图形
grammer = {
&start&: &F-F-F-F-F&,
&rules&: {&F&: &F-F++F+F-F-F&},
geometry = {
&rotate&: 72,
&actions&: {&-&: &left&, &+&: &right&, &F&: &forward&}
&/code&&/pre&&/div&&figure&&img src=&https://pic3.zhimg.com/v2-55f2c597fb6b163d0d4e5_b.jpg& data-size=&normal& data-rawwidth=&1290& data-rawheight=&336& class=&origin_image zh-lightbox-thumb& width=&1290& data-original=&https://pic3.zhimg.com/v2-55f2c597fb6b163d0d4e5_r.jpg&&&figcaption&不知名的图形 迭代次数 1 / 2 / 3 / 4&/figcaption&&/figure&&p&上面这个 L-system 实现的非常简单,只能描述『一笔画』的曲线。现在在几何意义上添加两个动作 —— 入栈 和 出栈&/p&&p&入栈代表将当前的 点和角度 入栈,出栈代表将当前的 点和角度 出栈,新的 L-system 如下(使用 [ 和 ] 表示这两个动作)&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&def replacement(str, rules, order):
for i in range(order):
for s in str:
if s in rules:
dst += rules[s]
return str
def interpretation(str, actions, rotate, angle, x, y):
import math
point_x = [x,]
point_y = [y,]
coordinates = [[point_x, point_y],]
stack = []
for s in str:
if s not in actions:
if actions[s] == &left&:
angle -= rotate
elif actions[s] == &right&:
angle += rotate
elif actions[s] == &forward&:
r = angle / 180.0 * math.pi
point_x.append(point_x[-1] + math.cos(r))
point_y.append(point_y[-1] + math.sin(r))
elif actions[s] == &push&:
stack.append((angle, point_x[-1], point_y[-1]))
elif actions[s] == &pop&:
angle, _x, _y = stack[-1]
stack = stack[:-1]
point_x = [_x,]
point_y = [_y,]
coordinates.append([point_x, point_y])
return coordinates
&/code&&/pre&&/div&&p&现在我们找几个示例来测试下&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&grammer = {
&start&: &X&,
&rules&: {&X&: &F+[[X]-X]-F[-FX]+X&, &F&: &FF&},
geometry = {
&rotate&: 25,
&actions&: {&-&: &left&, &+&: &right&, &F&: &forward&, &[&: &push&, &]&: &pop&}
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 4)
for i in range(4):
str = replacement(grammer[&start&], grammer[&rules&], i + 3)
coordinates = interpretation(str, geometry[&actions&], geometry[&rotate&], 60, 0, 0)
print(coordinates)
sub = ax[i]
sub.axis(&off&)
sub.set_aspect(&equal&)
for coordinate in coordinates:
x, y = coordinate
sub.plot(x, y)
plt.show()
&/code&&/pre&&/div&&figure&&img src=&https://pic2.zhimg.com/v2-61f50deed029f3bae20213_b.jpg& data-size=&normal& data-rawwidth=&1320& data-rawheight=&322& class=&origin_image zh-lightbox-thumb& width=&1320& data-original=&https://pic2.zhimg.com/v2-61f50deed029f3bae20213_r.jpg&&&figcaption&不知名植物一 迭代次数 3 / 4 / 5 / 6&/figcaption&&/figure&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# 不知名植物二
grammer = {
&start&: &X&,
&rules&: {&X&: &F[+X]-X&, &F&: &FF&},
geometry = {
&rotate&: 25,
&actions&: {&-&: &left&, &+&: &right&, &X&: &forward&, &F&: &forward&, &[&: &push&, &]&: &pop&}
&/code&&/pre&&/div&&figure&&img src=&https://pic3.zhimg.com/v2-d067c3abc85f636b4e54f8bb_b.jpg& data-size=&normal& data-rawwidth=&1372& data-rawheight=&466& class=&origin_image zh-lightbox-thumb& width=&1372& data-original=&https://pic3.zhimg.com/v2-d067c3abc85f636b4e54f8bb_r.jpg&&&figcaption&不知名植物二 迭代次数 3 / 4 / 5 / 6&/figcaption&&/figure&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# 不知名植物三
grammer = {
&start&: &FX&,
&rules&: {&X&: &FF+[+F]+[-F]&, &F&: &FF-[-F+F]+[+F-F]&},
geometry = {
&rotate&: 25,
&actions&: {&-&: &left&, &+&: &right&, &X&: &forward&, &F&: &forward&, &[&: &push&, &]&: &pop&}
&/code&&/pre&&/div&&figure&&img src=&https://pic1.zhimg.com/v2-7f91a1a147a2807efcc9acc8072ead99_b.jpg& data-size=&normal& data-rawwidth=&1374& data-rawheight=&580& class=&origin_image zh-lightbox-thumb& width=&1374& data-original=&https://pic1.zhimg.com/v2-7f91a1a147a2807efcc9acc8072ead99_r.jpg&&&figcaption&不知名植物三 迭代次数 3 / 4 / 5&/figcaption&&/figure&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# 不知名植物四
grammer = {
&start&: &F&,
&rules&: {&F&: &FF[-F++F][+F--F]++F--F&},
geometry = {
&rotate&: 25,
&actions&: {&-&: &left&, &+&: &right&, &X&: &forward&, &F&: &forward&, &[&: &push&, &]&: &pop&}
&/code&&/pre&&/div&&figure&&img src=&https://pic3.zhimg.com/v2-bc6dccfa2769f_b.jpg& data-size=&normal& data-rawwidth=&1444& data-rawheight=&1012& class=&origin_image zh-lightbox-thumb& width=&1444& data-original=&https://pic3.zhimg.com/v2-bc6dccfa2769f_r.jpg&&&figcaption&不知名植物四 迭代次数 2 / 3 / 4&/figcaption&&/figure&&p&&br&&/p&&p&&b&结语&/b&&/p&&p&L-system 的表达能力比上面描述的要更加强大。在实践中,一个完整 L-system 实现有很实际的应用,比如园林设计。在阅读关于空间填充曲线的资料,写了一些曲线实现,后来发现一个简单的 L-system 就有很强的表达能力,觉得非常有意思,于是写了本文。后面举的例子已经不是空间填充曲线了,但同样简单,若有兴趣,可以自定义编写 grammer 和 geometry,来看下会生成什么图形&/p&&p&&br&&/p&&p&欢迎关注我的专栏&/p&&a href=&https://zhuanlan.zhihu.com/c_& data-draft-node=&block& data-draft-type=&link-card& data-image=&https://pic4.zhimg.com/v2-13a65e2ecdc7_ipico.jpg& data-image-width=&240& data-image-height=&240& class=&internal&&面向工资编程 —— 收录 Java 语言的面试向文章&/a&&a href=&https://zhuanlan.zhihu.com/c_& data-draft-node=&block& data-draft-type=&link-card& data-image=&https://pic2.zhimg.com/v2-c6ff17724bac0d45adf943c05dfc48d9_ipico.jpg& data-image-width=&383& data-image-height=&383& class=&internal&&编程的基础和一些理论&/a&&a href=&https://zhuanlan.zhihu.com/c_& data-draft-node=&block& data-draft-type=&link-card& data-image=&https://pic1.zhimg.com/v2-bc4a8a0c85c930f69d905f_ipico.jpg& data-image-width=&430& data-image-height=&430& class=&internal&&编程的日常娱乐 —— 用 Python 干些有趣的事&/a&&p&&/p&
注:建议使用 Python 3,本文所有代码虽然可以使用 Python2 运行,但图像实现有些缺陷 使用 Python 可以用简单的逻辑画出一些的空间填充曲线,比如下面 Hilbert 曲线、Dragon 曲线 以及 Gosper 曲线,这些曲线都可以『一笔画』画出上面 3 种曲线的点生成算…
&p&在大型超大型web应用开发上,看好Angular。&/p&&p&&b&深度整合Typescript和Rxjs。&/b&&/p&&p&ts解决了工程化的问题,rxjs解决了开发速度的问题。&/p&&p&但是学习成本,可能对于Java,c#等OOP工程师来说比较容易上手,但是对于JavaScript工程师来说,少有工程化的经验,接受起来比较痛苦。&/p&&p&当然,不只是Angular可以采用Typescript开发,很多其他的Dom库都可以,Angular相比他们的优势在于:&/p&&ol&&li&&b&零配置&/b&&/li&&li&&b&深度整合设计模式&/b&&/li&&li&&b&约定才是框架的本质&/b&&/li&&/ol&&p&尤其是第三条,相信很多天才程序员都能复现Angular的设计模式和功能,但是由于并非“框架”,没有其他程序员跟进,显然就不能适用于大型超大型应用,毕竟&b&对于大项目来说,沟通往往会成为开发瓶&/b&颈。&/p&&p&rxjs很多人认为太重,没有必要,当然你也可以用很不优雅的toPromise方法来处理异步操作,甚至直接用behaviorObject.value也可以,但是当异步操作繁杂,重复,非一致的时候,rxjs可以很优雅地保证数据的稳定。&/p&&p&rxjs的运用一方面是为了处理这种复杂的异步逻辑,另一方面,就是为了让&b&异步数据流&/b&可以声明,而不用像promise那样声明冗长,或者async await那样函数化(数据就是数据),响应式是基于数据的响应式而不是基于函数。&/p&&hr&&p&小型应用上,看好vue&/p&&p&&b&绝大部分web应用,都应该只是小型应用!&/b&&/p&&p&公司官网,论坛,甚至是规模不大的电子商务网站和基本功能的OA,ERP系统,都只是小型web应用。它们数据源稳定,对于运营的要求不高,但是对加载速度等都有很高的要求。这个时候,小巧的vue就成了首选。&/p&&p&Proxy实现的响应式相比Angular的zone暴力代理和rxjs的复杂操作显得更加接地气,不需要额外地进行学习。&/p&&p&对象式的声明在UI实现上速度更快(不然你以为为什么做UI要用XML?)&/p&&p&api面积小,基础概念少,让你对项目的控制力更强。&/p&&p&生态虽然没有react那么热闹但是小而美的库也很多,nuxt的实现值得点赞。&/p&&hr&&p&个性化需求,中型应用,看好react。&/p&&p&在中大型应用中,不是一定要搞JAVA那一套的,而且在前端这种对工期要求很紧的领域,没必要因为添加新功能而更换新的平台,能用到rxjs和依赖注入的&b&前端应用场景&/b&并不多。&/p&&p&所以如果采用react,从项目一开始就渐进式地添加模块,往往更适合快速发展的产品。&/p&&hr&&p&综上所述,他们各自有各自的应用领域。&/p&&p&不过说句实在话,整个前端领域的项目用得到Angular,Vue和React的地方非常非常少。&/p&&p&SPA和混合应用的场景不多,所以看好谁我说不准。&/p&&p&&br&&/p&&p&&b&但是不能在HTML里面引入的Angular肯定是会玩完的。&/b&(毕竟有一部分前端都没接触过构建工具吧)&/p&
在大型超大型web应用开发上,看好Angular。深度整合Typescript和Rxjs。ts解决了工程化的问题,rxjs解决了开发速度的问题。但是学习成本,可能对于Java,c#等OOP工程师来说比较容易上手,但是对于JavaScript工程师来说,少有工程化的经验,接受起来比较痛苦…
&figure&&img src=&https://pic3.zhimg.com/v2-42e2fbf96f17f691ecb6_b.jpg& data-rawwidth=&750& data-rawheight=&500& class=&origin_image zh-lightbox-thumb& width=&750& data-original=&https://pic3.zhimg.com/v2-42e2fbf96f17f691ecb6_r.jpg&&&/figure&&p&最近在学习微信小程序开发,半个月学习下来,很想实战一下踩踩坑,于是就仿写了一个滴滴他们家的青桔单车小程序的前端实现,过程一言难尽,差不多两周时间过去了,发现小程序的坑远比想象的要多的多!!在实际练手中,完全是黑盒的,看到人家上线的小程序的效果,纯靠推测,部分效果在绞尽脑汁后能做出大致的实现,但是有些细节,费劲全力都没能做出来。很想一窥源码,查看究竟,看看大厂的前端大神们是如何规避了小程序的各种奇葩的坑。&/p&&p&于是就想到获取到小程序地源文件,然后再对其进行反编译还原为源代码,来作为学习参考。我百度了各种关于小程序地反编译教程,但是感觉都不太适合像我这样地初学小白,踩了挺多坑。在这里把我重新简化好的, &b&快速地获取一个微信小程序源码&/b& 的方式记录下来。&/p&&h2&简单聊一下 &code&xxxxx.wxapkg&/code&&/h2&&p&先来想想一个很简单的问题,小程序的源文件存放在哪?&/p&&ul&&li&当然是在微信的服务器上。&/li&&/ul&&h2&但是在微信服务器上,普通用户想要获取到,肯定是十分困难的,有没有别的办法呢?&/h2&&ul&&li&简单思考一下我们使用小程序的场景就会明白,当我们点开一个微信小程序的时候,其实是微信已经将它的从服务器上下载到了手机,然后再来运行的。&/li&&li&所以,虽然我们没能力从 &code&服务器&/code& 上获取到,但是我们应该可以从 &code&手机本地&/code& 找到到已经下载过的小程序源文件&/li&&/ul&&h2&那么如何才能在手机里找到小程序的源文件包呢?&/h2&&ul&&li&这里只以安卓手机为例,毕竟穷逼不曾拥有过苹果手机&/li&&li&具体目录位置直接给出:&/li&&ul&&li&&code&/data/data/com.tencent.mm/MicroMsg/{{一串32位的16进制字符串文件夹}}/appbrand/pkg/&/code&&/li&&/ul&&/ul&&p&&br&&/p&&ul&&li&在这个目录下,会发现一些 &code&xxxxxxx.wxapkg&/code& 类型的文件,这些就是微信小程序的包&/li&&/ul&&h2&准备材料&/h2&&ol&&li&node.js运行环境&/li&&/ol&&ul&&li&如果没有安装nodejs,请先安装一下&/li&&li&下载地址:&a href=&http://link.zhihu.com/?target=http%3A//nodejs.org/en/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&nodejs.org/en/&/span&&span class=&invisible&&&/span&&/a&&/li&&/ul&&ol&&li&反编译的脚本&/li&&/ol&&ul&&li&这里提供一个Github上 &code&qwerty472123&/code& 大神写的node.js版本的,当然也有其它版本的,这里我只是简单地用node.js版本举例&/li&&li&地址: &b&&i&&a href=&http://link.zhihu.com/?target=https%3A//link.juejin.im/%3Ftarget%3Dhttps%253A%252F%252Fgithub.com%252FqwertyFwxappUnpacker& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&github.com/qwerty47212…&/a&&/i&&/b&&/li&&/ul&&ol&&li&安卓模拟器(要求自带root权限)&/li&&/ol&&ul&&li&我使用的是 &code&夜神模拟器&/code& ,用来获取小程序源文件&/li&&li&下载地址: &b&&i&&a href=&http://link.zhihu.com/?target=https%3A//link.juejin.im/%3Ftarget%3Dhttps%253A%252F%252Fwww.yeshen.com%252Fcn%252Fdownload%252FfullPackage& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&www.yeshen.com/cn/download…&/a&&/i&&/b&&/li&&/ul&&h2&详细步骤:&/h2&&ul&&li&微信小程序的格式就是: &code&.wxapkg&/code&&/li&&li&.wxapkg是一个二进制文件,有其自己的一套结构。&/li&&li&关于.wxapkg的详细内容可以参考 &b&&i&&a href=&http://link.zhihu.com/?target=https%3A//link.juejin.im/%3Ftarget%3Dhttp%253A%252F%252Flrdcq.com%252Fme%252Fread.php%252F66.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&lrdcq大神的博文:微信小程序源码阅读笔记&/a&&/i&&/b&&/li&&li&但是这里有个 &b&坑&/b& ,想要进入到上面这个目录的话,用手机自带的文件管理器肯定是不行的, &code&安卓&/code& 或者 &code&iPhone&/code& 都要要用到第三方的文件管理器,比如: &code&RE文件管理器&/code& ,并且安卓需要取得root权限,而苹果手机肯定是要越狱的,且 &b&iphone的越狱难度&&安卓获取root&/b& ,不管越狱还是root,这都太费劲,当然有能力的同学可以直接从手机上来操作,但是这里 &code&不推荐从真机上获取&/code& 。&/li&&/ul&&h2&使用安卓模拟器获取到.wxapkg文件&/h2&&p&不用越狱,不用root,使用电脑端的 &b&安卓模拟器&/b& 来获取是一个 &b&非常简单快捷且万能的&/b& 获取方式,具体步骤如下:&/p&&ol&&li&打开安装好的安卓模拟器,并在模拟器中安装 &code&QQ&/code& 、 &code&微信&/code& 、 &code&RE管理器&/code&&/li&&/ol&&ul&&li&&code&QQ&/code& 、 &code&微信&/code& 在模拟器自带的应用商店里搜索下载安装即可&/li&&li&&code&RE管理器&/code& 的下载地址: &b&&i&&a href=&http://link.zhihu.com/?target=https%3A//link.juejin.im/%3Ftarget%3Dhttps%253A%252F%252Fpan.baidu.com%252Fs%252F1PPBx08rNutXxhlMMJbuTpQ& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&pan.baidu.com/s/1PPBx08rN…&/a&&/i&&/b&&/li&&li&下载好后直接拖拽进打开的模拟器窗口就会自动安装&/li&&/ul&&ol&&li&设置一下模拟器&/li&&/ol&&ul&&li&以我个人认为比较好用的 &code&夜神模拟器&/code& 举例&/li&&li&首先到模拟器内部设置超级用户权限&/li&&/ul&&figure&&img src=&https://pic3.zhimg.com/v2-bd5f9debf0aa5cef456dbd0c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&550& data-rawheight=&328& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic3.zhimg.com/v2-bd5f9debf0aa5cef456dbd0c_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-d220aac7c4be1ab53e0268_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&550& data-rawheight=&1003& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic1.zhimg.com/v2-d220aac7c4be1ab53e0268_r.jpg&&&/figure&&p&&br&&/p&&ul&&li&这些操作的目的都是为了能让 &code&RE管理器&/code& 顺利的获取到ROOT权限&/li&&/ul&&ol&&li&接下来在模拟器里打开微信,然后在微信中运行你想要获取的下程序(这其实是让微信把小程序的源文件包从服务器下载到了本地了)&/li&&/ol&&ul&&li&就以我说的这款青桔单车的小程序举例(希望滴滴的大神不会想打死我~)&/li&&li&在模拟器微信中运行一下后, &b&直接切回模拟器桌面运行RE浏览器&/b& 来到目录&/li&&li&&code&/data/data/com.tencent.mm/MicroMsg/{{一串32位的16进制字符串文件夹}}/appbrand/pkg/&/code&&/li&&li&就抵达了目的文件夹&br&&/li&&/ul&&figure&&img src=&https://pic1.zhimg.com/v2-cc703b5775beea55a1127826bed3d90c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&550& data-rawheight=&347& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic1.zhimg.com/v2-cc703b5775beea55a1127826bed3d90c_r.jpg&&&/figure&&p&&br&&/p&&ul&&li&你会看到发现里面的一些.wxapkg后缀的文件,就是它们没错啦,可以根据使用的时间来判断那个是你刚才从服务器下载过来的&/li&&li&一般小程序的文件不会太大,可以结合时间来判断,长按压缩所选文件,然后再将压缩好的包通过QQ发送到 &code&我的电脑&/code&&/li&&li&如果不进行压缩的话,是无法将这个文件通过QQ来发送的&br&&/li&&/ul&&figure&&img src=&https://pic4.zhimg.com/v2-fb017ead7faeb2f902bb9b3_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&550& data-rawheight=&455& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic4.zhimg.com/v2-fb017ead7faeb2f902bb9b3_r.jpg&&&/figure&&p&&br&&/p&&ul&&li&所以QQ的这个功能可以让我们很方便的拿到源文件,而不必到电脑目录去找模拟器的文件目录。&/li&&li&解压。这样几步简单操作,就成功拿到了小程序的源文件了。&/li&&/ul&&h2&使用反编译脚本解包 wxapkg&/h2&&ul&&li&到这里你应该已经将反编译脚本从github下载 或者 clone 到本地某个目录&/li&&li&打开nodejs命令窗口&/li&&li&cd 到你clone或者下载好的反编译脚本目录下&/li&&li&在node命令窗口中依次安装如下依赖:&br&npm install esprima&br&&br&npm install css-tree&br&&br&npm install cssbeautify&br&&br&npm install vm2&br&&br&npm install uglify-es&/li&&li&安装好依赖之后,就是最后一步了,反编译 .wxapkg 文件&/li&&li&在当前目录下输入&br&node wuWxapkg.js [-d] &files...&
//files 就是你想要反编译的文件名&br&例如:我有一个需要反编译的文件 &code&_.wxapkg&/code& 已经解压到了D盘根目录下,那么就输出命令&br&node .\wuWxapkg.js D:\_.wxapkg&/li&&li&回车运行&br&&/li&&/ul&&figure&&img src=&https://pic4.zhimg.com/v2-3d328298bfa0efb51a5e7_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&550& data-rawheight=&255& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic4.zhimg.com/v2-3d328298bfa0efb51a5e7_r.jpg&&&/figure&&p&&br&&/p&&ul&&li&反编译脚本就能一步将.wxapkg 文件还原为微信开发者工具能够运行的源文件, &b&目录地址和你反编译的文件地址是一样的&/b&&br&&/li&&/ul&&figure&&img src=&https://pic2.zhimg.com/v2-29aacc40063dd_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&550& data-rawheight=&211& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic2.zhimg.com/v2-29aacc40063dd_r.jpg&&&/figure&&p&然后在微信开发者工具新增项目即可打开&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-a710b3e53a4629ed4cac61c8d9d25c91_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&411& data-rawheight=&474& class=&content_image& width=&411&&&/figure&&p&&br&&/p&&ul&&li&运行成功,源码获取完成&br&&/li&&/ul&&figure&&img src=&https://pic4.zhimg.com/v2-328cac06bd3a0243200beb_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&550& data-rawheight=&390& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&https://pic4.zhimg.com/v2-328cac06bd3a0243200beb_r.jpg&&&/figure&&p&&br&&/p&&h2&只需两步即可完成&/h2&&p&至此我们就通过非常简单的方式获取到了一个想要的小程序源文件,并对齐进行了反编译还原 以后想要再反编译其他的小程序,非常快速, &b&真的只需要两步&/b&&/p&&ol&&li&&b&使用模拟器找到小程序.wxapkg文件&/b&&/li&&li&&b&使用nodejs 反编译脚本将.wxapkg文件反编译&/b&&/li&&/ol&&p&使用此方法,绝大部分的小程序都能正常反编译出来,但是也会有一些特殊的情况,具体可以查看 &code&qwerty472123&/code& 大神的readme文件&/p&&h2&写在后面的话&/h2&&p&.apk 之类的文件反编译非常困难,而小程序竟可以如此轻松随意地被获取到源码,根源在于小程序的开发团队并没有对小程序的执行文件进行有效的保护,也就是加密,所以我们才能使用别人写好的脚本直接进行反编译,其过程类似于解压。&/p&&p&实际上,小程序只是很简单的将图片、js和json文件压在一起,而压制的过程就是Wxml -& Html、 Wxml -& JS、Wxss -& Css,转换后文件二进制格式跟后缀名为wx二进制格式完全一致。&/p&&p&上线的源代码能如此简单的被获取到,不得不说小程序的源码安全存在很大的隐患,这一点很多开发者应该也知道,所以发现有些小程序会将重要的js逻辑代码柔在一个js文件中,这样,即使被获取了源码,也不是很容易读懂,但是任然避免不了被窥视的问题。 小程序作为微信生态内的新生力量,不仅被官方,也被很多开发者和内容创业者寄予厚望,处于对代码的安全性的考虑,这个漏洞迟早有一天会被 &b&修复(封掉)&/b& 的。&/p&&p&所以这种这里介绍的获取小程序源码的方法,应该是不会太长久的。&/p&&p&&br&&/p&&blockquote&&i&作者:&/i&行无忌&br&&i&链接:&/i&&a href=&http://link.zhihu.com/?target=http%3A//www.wxapp-union.com/portal.php%3Fmod%3Dview%26aid%3D4104& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&只需两步获取任何微信小程序源码-实战教程-小程序社区-微信小程序-微信小程序开发社区-小程序开发论坛-微信小程序联盟&/a&&br&&i&著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。&/i&&/blockquote&
最近在学习微信小程序开发,半个月学习下来,很想实战一下踩踩坑,于是就仿写了一个滴滴他们家的青桔单车小程序的前端实现,过程一言难尽,差不多两周时间过去了,发现小程序的坑远比想象的要多的多!!在实际练手中,完全是黑盒的,看到人家上线的小程序的…
&a class=&video-box& href=&//link.zhihu.com/?target=https%3A//www.zhihu.com/video/541696& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&https://pic2.zhimg.com/v2-bbfee82e87f95c1cab088db12dd371c2.png& data-lens-id=&541696&&
&img class=&thumbnail& src=&https://pic2.zhimg.com/v2-bbfee82e87f95c1cab088db12dd371c2.png&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&https://www.zhihu.com/video/541696&/span&
&/a&&a class=&video-box& href=&//link.zhihu.com/?target=https%3A//www.zhihu.com/video/199616& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&https://pic4.zhimg.com/v2-6137e6fcac6.png& data-lens-id=&199616&&
&img class=&thumbnail& src=&https://pic4.zhimg.com/v2-6137e6fcac6.png&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&https://www.zhihu.com/video/199616&/span&
&/a&&p&python写的连连看外挂,图二时间间隔设置成了0,效果有点吓人。用的是简单的opencv图像识别结合连连看的算法,如果关注度足够,我会回来补上具体的实现思路和源码地址。(开源了已经)希望不会接到腾讯爸爸的律师函?&/p&&hr&&p&&b&日更新:&/b&&/p&&p&让大家失望了,并没有收到律师函或者offer,哈哈。 不过收到了知乎管理员的恐吓信,所以今天不得不来更下答案。恐吓信内容如下:马赛克里是原答案:&/p&&figure&&img src=&https://pic1.zhimg.com/50/v2-7efe5ecaf66_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&750& data-rawheight=&1334& class=&origin_image zh-lightbox-thumb& width=&750& data-original=&https://pic1.zhimg.com/50/v2-7efe5ecaf66_r.jpg&&&/figure&&p&所以很遗憾的告诉大家,本次更新后源码连接我就删了,还有管理员提到的内容的部分,我也直接删了就。毕竟在人家的地盘装逼,人家的规矩还是要遵守的,我倒不是说怂或者害怕啥的,年纪轻轻一大小伙子踏踏实实搞技术没什么好怕的,我就是单纯的有些瑟瑟发抖~~&/p&&p&毕竟人怕出名猪怕壮,现在7k+的赞确实是影响力大了一点。影响力大了,自然就众口难调了,一开始大家清一色的点赞感谢,还有捧我大佬什么的,后面慢慢的开始出现不一样的声音了,有骂我不道德的,有威胁要举报的,甚至还有用些诅咒性的语言问候我家人的。这我实在无可厚非,龙蛇混杂才是大千世界。很感谢你们的嫉恶如仇的态度,我也很希望你们的态度和言论,可以让我们的世界变得更好!&/p&&p&我上次答案就说了,我的初衷就是技术分享,我不希望有人用它来获取商业利益,降低游戏体验。所以我并没有提供具体针对某官方游戏的配置信息,后来在评论中有把自己试出来的配置信息贴出来的,我直接都删了。所以这次改完答案后,源码连接也就不提供了,评论中出现的源码连接啥的我也会一并删除,请谅解。&/p&&p&收到了很多私信有项目合作的,开心的我以为有私活儿接了,结果问一个做外挂,问一个做外挂,利润还颇为丰厚,麻烦大佬们这样的项目不要再找我了,我不是看不上你们的项目和钱,我是真的不会做。。。&/p&&p&还有大家谁把这程序搞出来了,在联系模式里爽爽就行啦,别搞得好好的游戏跟神仙打架似的,反而没啥意思不是?&/p&&p&好了,后续的内容扯完了,我们把镜头交给原答案:&/p&&hr&&p&先手动来条华丽的分割线&/p&&p&~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&/p&&p&这刚刚有了知乎账号不到两周还,第一次在知乎回答,不到两天的时间,快破800的点赞,440的收藏,130的关注,66的感谢,还有100多条五花八门的评论着实是吓到我了。刚刷到这个问题的时候就觉得小猪佩奇都能赞到3k+,那我是不是也可以?就尝试性的发了这个外挂出来,看来冲击力实在不小,都有人私信问我是不是骗子了,吓得我赶紧回来补上约定好的实现思路和源码连接。承蒙大家厚爱,现在我来好好回答一下这个问题。&/p&&h2&源码&/h2&&p&源码连接:先点这里,然后点star(假装这里仍然有链接)&/p&&p&这个小外挂用python2写出来有将近半年了,挂到github上的版本我想用python3重构,当时只写了个开头后来不了了之了。这篇回答发出来,关注度如此之高,这才想起来我的github上挂的是半喇项目,尴尬我的今天趁下班时间赶紧写完了python3的版本,并且把思路代码都理了理。如果觉得还不错就给个star,毕竟还年轻,虚荣心比较强,谢谢!&/p&&p&&b&需要使劲敲黑板强调一下的是:没啥强调的了(7月11日源码链接已经删了,这里要强调的内容,也就没意义了,哈哈)&/b&&/p&&h2&实现思路&/h2&&p&下面的内容,伸手党可以不用看了,毕竟大家更感兴趣的,肯定是上面那个链接&b&(嗯,可惜现在已经没了)&/b&。&/p&&p&项目一共350行左右的源码,注释150行,是的,实现起来比你想象的简单的多。接下来我用我的方式讲解一下这个外挂是怎么实现的,尽可能简洁,让绝大部分人都能听懂。&/p&&ul&&li&&b&首先,我们先想想人类是怎么玩连连看这个游戏的?&/b&&/li&&/ul&&p&游戏开始,纵览全局,一眼扫到能够相连的两个相同的图片,就用鼠标去点,先点第一个,再点第二个,随着“撕拉”一道闪电两个方块随即爆炸,爽的不要不要,以此类推直到游戏结束,通过以上的操作可以细化出这样几个点来:&/p&&ol&&li& 图片要相同。这个我们人类可以一眼分辨出来&/li&&li& 两个点可以连通。很多人玩到现在也不是很清楚怎样能连,怎样不能,反正看了就知道,具体是啥硬性规则也并不是特别清楚。&/li&&li& 点击,鼠标一个一个的点,如果刚点过的两个图片相同并且可以连通,就是“撕拉”一道闪电让你爽一下。&/li&&/ol&&ul&&li&&b&回到问题,人类是这样玩的?那机类能不能也这么玩?&/b&&/li&&/ul&&p&答案是肯定的,计算机运算速度那么快,如果能想办法让他用和人类一样的思路去操作,那我们岂不是能轻易享受到“撕拉撕拉”的快感?而唯一需要我们做的,就是躺好,让她自己动。哦它!错别字!&/p&&p&想到这问题就清晰一些了,我们想让电脑按照我们的方式去执行和我们一样的操作,借助CPU发热的淫威,达到我们人类难以企及的速度,就是酱紫。那么计算机怎么像我们一样思考和操作呢?回到上面分析出的三点:&/p&&ol&&li&它要能认出屏幕上相同的图片。&/li&&li&它要知道某俩图片能不能相连。&/li&&li&它要能像人一样去对着屏幕啪啪啪....地点击。&/li&&/ol&&p&就像把大象装进冰箱一样,让电脑代替人脑,需要的也就是这么简单的三步。&/p&&ul&&li&&b&第一步:它要能认出屏幕上相同的图片。&/b&&/li&&/ul&&p&程序它如何能认识屏幕中的游戏中的一个一个的小方块呢?你肯定想到了图像识别,屏幕中间一个个的小方块是很有规律的,也有明显并且规律性的色值的梯度变化,通过一些图像识别的算法一定可以让程序认出屏幕上的小方块来。没错,但这样做很麻烦,&b&这里我一定要跟在座的提一下:无论是产品设计还是编码实现,一定要遵循一个核心原则:大道至简!&/b&什么叫大道至简?意思就是复杂的我也不会。&/p&&p&那简单的怎么做?首先,找到游戏窗体的位置(windows API),然后从屏幕上截张图(PIL),游戏窗体顶点的横纵坐标各加上一个数字,就找到了游戏区域(图中绿框),然后,通过图像切片的方式,从点C开始,分别以方块宽度为高度为步长,把图像切割成n个小块,然后再比较这些图片是否相等,一样的就用同样的数字标识,空白就用0,就这样简单粗暴地完成了第一步。&/p&&figure&&img src=&https://pic2.zhimg.com/50/v2-79aa84f329ae1c998bde_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1366& data-rawheight=&768& class=&origin_image zh-lightbox-thumb& width=&1366& data-original=&https://pic2.zhimg.com/50/v2-79aa84f329ae1c998bde_r.jpg&&&/figure&&p&至于我怎么知道方块的宽度高度,还有从顶点到游戏区域的距离?这个我是截图拿PS看的,不然还拿尺子量么。。。&/p&&ul&&li&&b&第二步:判断两张图是否能够相连&/b&&/li&&/ul&&p&图像转化成数据了,数据改怎么进行处理?&/p&&p&这里就得扯一下连连看的算法了,它的算法和它的规则关联度很大,它的规则是和拐点相关的:&b&两个方块的通路上,最多可以有两个拐点,如果用两个拐点还连不上,那他们就不能连通。&/b&落实在算法上其实很好写也:两个点能否直连是很好判断的,只需要判断两点之间的通路上是不是都为0就可以。那么两点通过一个拐点连通的情况,就是其中一点到拐点,再从拐点到另一点两个直连的判断。那么两个拐点的情况,就是一个点到拐点的直连+一个拐点到另一点的单拐点的情况进行判断。这样写下来,几乎全是嵌套调用,最后全部都集中在直线的校验上。&/p&&ul&&li&&b&第三步:如果能够相连,模拟鼠标点击屏幕&/b&&/li&&/ul&&p&第二部判断出的两个点可以相连,那需要程序点击一下两个点就可以,通过刚才的判断两个点的坐标是可以知道的,那只需要再向两个坐标发送鼠标点击的时间就可以。这里通过python win32的API就可以实现模拟,贴心的答主已经在源码开头附上pywin32下载链接了。&/p&&ul&&li&&b&最后,重复以上步骤&/b&&/li&&/ul&&p&电脑会以惊人的速度向你反馈“撕拉撕拉”的快感。这里请允许我再装个逼,上面的视频2我搞错了,是时间间隔0.01秒的情况,真实的0间隔效果是酱紫的:&/p&&a class=&video-box& href=&//link.zhihu.com/?target=https%3A//www.zhihu.com/video/663040& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&https://pic2.zhimg.com/80/v2-1ef646aadea7521_b.jpg& data-lens-id=&663040&&
&img class=&thumbnail& src=&https://pic2.zhimg.com/80/v2-1ef646aadea7521_b.jpg&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&https://www.zhihu.com/video/663040&/span&
&/a&&h2&一些闲蛋&/h2&&p&接下来就是一些闲扯的内容了,是我的一些看法和讨论,可能没什么技术含量和价值,不喜勿喷。&/p&&ul&&li&&b&说好的图像识别呢?&/b&&/li&&/ul&&p&相信很多人看了思路和源码一定很失望,根本没有什么高端的算法和逻辑,说好的图像识别,也就是用了一下opencv的函数比较了一下图像是否相等。当然,外挂确实实现了还很吊炸天。理想状态下当然是通过图像识别找出相同的图片然后分析计算然后执行自动消除的操作。但是不那么做的理由我在上面也说过了,我确实不会....-_-||&/p&&ul&&li&&b&程序中可改进的地方还有很多&/b&&/li&&/ul&&p&1、这个外挂程序的局限性比较大,从我上面的分析就可以知道很多都是基于固定坐标来算的,那其实只要腾讯爸爸把这个游戏做的支持缩放,这个外挂也就跪了。但是腾讯没有,自打我有记忆以来,这游戏怕是有15年没更新了,600*800的像素在我同事的外星人上显示地像个幼儿版本。可能是看不上这一天两万人的用户量吧,还是开发新版本的欢乐斗地主更挣钱。&/p&&p&2、如果速度设置的较慢,让别人先赢了,将是一件比较尴尬的事情,别人赢了你再点击屏幕已经无效了,但是程序继续运行仍然会让鼠标在对应的位置点来点去。你还没法移动它去停止程序,你鼠标还没挪走呢,就又给你挪到其他位置了。此处应该设置个中断机智,能够随时停止程序的。&/p&&p&3、我在程序中使用的是opencv+numpy进行的图片读取,切片,还有图片是否相等的校验。后来同事给我提供了一种思路:1、PIL本身就可以进行图片切片,2、operater.eq()可以校验两个对象是否一致,用来校验切片出来的图像是完全可以的。 这样的话根本就不需要opencv和numpy,什么图像识别,根本不需要的,如果那么做,代码量还可以比现在更精简。&/p&&ul&&li&&b&关于外挂&/b&&/li&&/ul&&p&关于外挂有很多中办法实现,我说几种主流的,大家评论里也已经多得五花八门了,&/p&&p&1、其中很大一部分,也是绝大多是外挂的主流做法,就是直接在&b&本机改内存&/b&。你的游戏运行在我这里,代码就得加载到我的内存里运行,那么内存里的数据再抽象,总有高手能给它鼓捣出来。就比如说这个连连看,我也可以通过读取内存的手段直接拿到它方块布局的数据,直接把这个数据全改成0,那立马就赢了。但这样做很麻烦,&b&这里我一定要跟在座的提一下:无论是产品设计还是编码实现,一定要遵循一个核心原则:大道至简!&/b&什么叫大道至简?意思就是复杂的我真的不会。。。&/p&&p&有一些游戏数据必须要在本地进行处理的,很容易遇到这种外挂,比如地下城与勇士无限刷图啦,更比如吃鸡,就说吃鸡,这样的第一人称射击游戏,打一枪子弹中没中,不可能放到服务器去判断,一是判断不过来,二是受网络的影响实时性根本达不到要求。所以你一枪子弹打出去中没中,一定是放在本地进行计算的,既然是在本地内存里,一旦防范不到位那就有人能给你改,我们所谓的“飞天遁地锁血金身”什么的。像LOL就不多存在这样类型的外挂,一方面肯定是反外挂投入的力度大,另一方面就是因为你的操作全部都是由服务器来进行计算并反馈的,不存在太多本地数据篡改的风险。&/p&&p&2、另一种外挂,不在本机改内存,而是通过网络去骗数据,常见于数据协议被黑客窃取或破解,那他就可以按照协议格式发伪造的数据,来骗服务器。这种外挂我见过的比如GTA5 online版本,当时答主的舍友花50块买的外挂,头上一个劲儿的往出冒钱,外挂弄出的钱,退出后重新登录会消失,但是如果这些钱用来买了资产,那资产就实打实的是你的了。看上去也是很爽,感觉那外挂应该是了窃取某个加钱的接口,然后发模拟数据一个劲儿的刷。&/p&&p&3、再有,就是我的这种外挂,用程序来模拟用户的某些操作,类似于按键精灵的意思,得益于计算机优秀的运算速度,往往能达到人类不可能达到的水平。除了我这个连连看,还有之前微信跳一跳的外挂也是如此。而这种外挂也很难防范,有些时候程序无法判断操作是来源于用户还是代码。&/p&&ul&&li&&b&关于攻防&/b&&/li&&/ul&&p&我是这个外挂的作者,所以也想说说关于如何防范这个外挂,以下来说说我替鹅厂想的一些法子来阻止我这个外挂。&/p&&p&1、&b&最行之有效:窗体缩放。&/b&如果这个游戏的窗体可以缩放,那我这个外挂基本上算是废了,除非你每次玩的时候都能缩成固定的大小,并且每次保证都一样。如果真的修改地支持窗体的缩放了,那我的外挂就不得不通过真正的图像识别来搞了。当然,那样会很麻烦....我不会。&/p&&p&2、&b&检测时间间隔,如果每次间隔都一样,则视为外挂。&/b&这属于比较蠢的办法之一,你是不知道python中生成个随机数有多简单,随便弄个0.5~2秒随机,那家伙比真人还真!&/p&&p&3、&b&通过驱动级别的检测,看是否有鼠标输入。&/b&这个原理很简单,实现起来很难。让程序的代码深入驱动底层去检测,如果没有捕获到鼠标点击,但是程序却收到了鼠标事件,说明这次点击时程序模拟的,直接过滤掉。但是这样做的代价很大,驱动底层的windwos编程带来的可能是巨大的兼容性难题,XP、win7、win10很有可能不一样。与其这样,干嘛还在每天2W用户量的连连看上面较劲,投入人力物力去开发欢乐斗地主不是更好么。&/p&&p&当然,鹅厂是完全有这样的能力和技术手段的。答主曾经遇到过一个windows键盘监听器,用C++钩子实现的全局键盘监听,可以监听一切用户输入。但腾讯QQ的登录框的密码,则是完全兼听不到的,这说明腾讯在此处做了比钩子更加底层的安全处理,也就是驱动级别的处理。题外话:银行官网登录时让下载的安全控件也可以提供这种级别的保护的,四大行只有一个会被钩子监听到按键输入,是哪一个我就不说了,曾经提交过反馈,不知现在处理了没有。&/p&&ul&&li&&b&这个外挂其他语言能不能做&/b&&/li&&/ul&&p&可以!答案是一定可以,这其中用到的技术没有一个是非python干不了了,只能说用其他语言,可能代码量多少的问题,比如我python用了200行有效代码,可能go需要300行? C++400行? java2000行?
大概这个行情吧。&/p&&p&哦,当然不是任何语言都可以,html和css就不行。&/p&&ul&&li&&b&关于评论和私信&/b&&/li&&/ul&&p&我刚刚才加入知乎,第一次回答有如此的关注度肯定是开心的,但是大家不要再在私信和评论里一口一个大佬大神了,又是问我要代码,又是问我推荐学习路线,问我推荐书籍的。作为程序员拿着不到5K的月薪,这么搞得我心里着实很慌。&/p&&p&还有问我要连连看源码的,这个视频中的连连看是腾讯QQ的连连看,不是我写的,所以你要连连看源码的话....我还真的有:&a href=&//link.zhihu.com/?target=https%3A//github.com/TheThreeDog/PictureMatching& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&王者荣耀风格的连连看&/a&。这个也就是我外挂项目中捆绑销售的连连看游戏,Qt C++做的,如果能加上“撕拉”的闪电,就更好了。拿去看看就行了,别拿去充当什么课设毕设,这游戏硬让我学弟妹们拿去给三四个人做毕设了,后果....&/p&&p&虽然我原本压根没打算入知乎的坑,但是一波儿回答让我吸了这么多赞还是蛮开心的,如果说问我出名后想做什么事情的话,我想可能是先给自己搞个头像?&/p&&p&PS:呀!刚才又看了一下,评论里没有叫大佬大神的哈,
飘了飘了~~&/p&&ul&&li&&b&关于代码中不给针对QQ连连看的数据&/b&&/li&&/ul&&p&外挂这种东西一定会多多少少损害到其他公司的商业利益,虽然鹅厂还轮不到我来考虑人家的商业利益,但是我仍然不希望外挂的配置代码从我手中散播出去。代码的开源一是为了交流和学习,二是为了Github上多多的star(不要脸到我自己都怕)。我也不扯什么伦理道德,我能做的,就只是管好自己。作为原作者也希望大家都能够做到:&b&不要在公开场合散布有关破解QQ游戏连连看的配置信息,不要将此代码用于任何商业用途。&/b&&/p&&p&还有就是答主内心比较脆弱,以上言论 有何不妥欢迎随时交流探讨,但是谢绝辱骂。&/p&&p&洋洋洒洒墨迹完,已经深夜了,祝大家好梦,就这样。&/p&
python写的连连看外挂,图二时间间隔设置成了0,效果有点吓人。用的是简单的opencv图像识别结合连连看的算法,如果关注度足够,我会回来补上具体的实现思路和源码地址。(开源了已经)希望不会接到腾讯爸爸的律师函?日更新:让大家失望了,并没有…
&p&进公司第一个项目就是用Vue写的,是一个大型的复杂应用,写了半年多发现Vue对我来说不够用了,或许是我个人能力不够吧。受到redux的单一store影响,我把很多组件的状态全部塞到vuex里去,跨组件调用是爽了,但是双向绑定就麻烦了,然后发现store树越来越大,后面分模块了还是好大,由于ide不能智能提示,我状态里有个属性名记不太清只能到js里面找。请求用的axios,也发现一些难以解决的痛点,例如cancel的api比较难用?创建了多个axios实例后又如何能被一个统一的全局拦截器拦截?防抖节流需要引入第三方库,合并请求只有Promise.all?&/p&&p&以上只是列举了我用vue开发中的部分痛点。我是菜鸟,各位前端大神勿喷。&/p&&p&&br&&/p&&p&直到后来为了帮一个公司的前端妹纸(我的女神)解决问题,她的项目组是用angular的。逼迫自己去学angular,然后一发不可收拾,我发现我已经爱上她了。我之前在项目上遇到的诸多痛点都有简单的解决方案,又有ts和rxjs加持让开发效率快得飞起,健壮性也得以保证。我可以从html模板里直接跳转到ts中的方法名,可以直接在vs code里打断点调试,可以快速查找到某个方法或属性的定义和引用。利用依赖注入系统,可以很方便利用服务类做组件间通信和其他各种事。&/p&&p&最让我喜欢的是angular的响应式表单功能。FormBuilder类让你很轻易建立一个表单模型对象,可以设置每个字段的初始值,同步验证器,异步验证,而且也内置了一些常用的验证器例如字段长度,非空,正则,也可以自己按照业务自定义验证器。这个表单模型跟html模板双向绑定,而且ng能知道你动过某个控件没有,改过它的值没有,现在验证错误是属于哪个验证器不通过。假如用vue和react在不借助第三方库的话要实现这套逻辑估计得写很多代码。&/p&&p&&br&&/p&&p&很多人觉得angular难学,大部分应该都是看网上或者听别人说的吧,当你真正去深入学习过你会发现其实也没那么难。其实angular的基本使用不难,难的是那些你官网教程里没有你需要自己去翻API文档和网上查资料学的。他们并不是必须的,而是当你感觉不够用了或者需要实现某个复杂功能的时候才需要去了解的。其中学习过程好比打怪升级,例如当你今天学会了API里某个类的并解决了一个棘手的问题时你会很有成就感。&/p&&p&&br&&/p&&p&如果官方的教程你看完了我只能说你其实只掌握了ng的30%,但也基本够用了。剩下的在哪里呢?&/p&&p&rxjs 10%,官方API文档30%,cdk 10%,使用经验20%&/p&&p&&br&&/p&&p&angular就像个知识宝库,永远有东西可以让你学习,这样才更有追求。&/p&&p&例如官方教程里你看到只有ngIf,然后不懂的人就开始喷怎么没有像vue里的v-else?其实ng是有的,ngIf then 。所以有很多隐藏的技巧需要你自己去发现探索。&/p&&p&&br&&/p&&p&然后题主说angular打包体积过大限制了它在移动端发展。那你又可知最新的angular第三代渲染引擎ivy已经把tree shaking做得更极致了,根据ng-conf大会上的ppt得知基于开启ivy引擎渲染后hello world 只要2.7kb,所以没有真正使用过ng的人别再跟风喷angular体积大性能不好。&/p&&figure&&img src=&https://pic4.zhimg.com/50/v2-11b3ecdac8f2_b.jpg& data-rawwidth=&2208& data-rawheight=&1242& data-size=&normal& class=&origin_image zh-lightbox-thumb& width=&2208& data-original=&https://pic4.zhimg.com/50/v2-11b3ecdac8f2_r.jpg&&&/figure&&p&另外题主还说到angular只是Google一小波人在开发,可你又知就是这一小波人开发的angular的每个版本都经过Google内部至少600+产品的考验?&/p&&p&&br&&/p&&p&总结一下,只有当你真正体验过不同框架的开发后,你才会真正感受到它们之间的差异,用合适的框架去解决合适的问题才是最明智的选择。angular的定位就是大型复杂应用,如果你用简单的框架去做复杂的事情,那只会让事情变得更复杂。&/p&&p&我觉得用angular做工程化是最容易的,因为Google已经把他们认为最优的解决方案摆在那了,也有风格指南,模块也帮你细分好了。而用vue和react的话,你第一就要对诸多第三方库或解决方案做出选择。层级划分,模块管理,通用模块设计,webpack配置等等大部分要自己去弄,所以更考验你的一个工程设计能力。当然很多人的应用都比较简单,所以还没需要用到这么复杂的设计。&/p&&p&&br&&/p&&p&总之我觉得angular是个真正意义上的框架,它给出了复杂应用会遇到的问题的解决方案,真正的一站式构建,省心。&/p&
进公司第一个项目就是用Vue写的,是一个大型的复杂应用,写了半年多发现Vue对我来说不够用了,或许是我个人能力不够吧。受到redux的单一store影响,我把很多组件的状态全部塞到vuex里去,跨组件调用是爽了,但是双向绑定就麻烦了,然后发现store树越来越大…
&p&WebSocket是为了解决双向通信的问题,因为一方面HTTP的设计是单向的,只能是一边发另一边收。而另一方面,HTTP等都是建立在TCP连接之上的,HTTP请求完就会把TCP给关了,而TCP连接本身就是一个长连接吗,只要连接双方不断关闭连接它就会一直连接态,所以有必要再搞一个WebSocket的东西吗?&br&&br&我们可以考虑一下,如果不搞WebSocket怎么实现长连接:&/p&&p&(1)HTTP有一个keep-alive的字段,这个字段的作用是复用TCP连接,可以让一个TCP连接用来发多个http请求,重复利用,避免新的TCP连接又得三次握手。这个keep-alive的时间服务器如&a href=&https://link.zhihu.com/?target=https%3A//zh.wikipedia.org/wiki/HTTP%25E6%258C%%25B9%%25BF%259E%25E6%258E%25A5& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Apache&/a&的时间是5s,而&a href=&https://link.zhihu.com/?target=http%3A//nginx.org/en/docs/http/ngx_http_core_module.html%3F%26_ga%3D2.keepalive_timeout& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&nginx&/a&默认是75s,超过这个时间服务器就会主动把TCP连接关闭了,因为不关闭的话会有大量的TCP连接占用系统资源。所以这个keep-alive也不是为了长连接设计的,只是为了提高http请求的效率,而http请求上面已经提到它是面向单向的,要么是服务端下发数据,要么是客户端上传数据。&/p&&p&(2)使用HTTP的轮询,这也是一种很常用的方法,没有websocket之前,基本上网页的聊天功能都是这么实现的,每隔几秒就向服器发个请求拉取新消息。这个方法的问题就在于它也是需要不断地建立TCP连接,同时HTTP头部是很大的,效率低下。&/p&&p&(3)直接和服务器建立一个TCP连接,保持这个连接不中断。这个至少在浏览器端是做不到的,因为没有相关的API。所以就有了WebSocket直接和服务器建立一个TCP连接。&/p&&p&TCP连接是使用套接字建立的,如果你写过Linux服务的话,就知道怎么用系统底层的API(C语言)建立一个TCP连接,它是使用的套接字socket,这个过程大概如下,服务端使用socket创建一个TCP监听:&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span&&/span&&span class=&c1&&// 先创建一个套接字,返回一个句柄,类似于setTimout返回的tId&/span&
&span class=&c1&&// AF_INET是指使用IPv4地址,SOCK_STREAM表示建立TCP连接(相对于UDP)&/span&
&span class=&kt&&int&/span& &span class=&n&&sockfd&/span& &span class=&o&&=&/span& &span class=&n&&socket&/span&&span class=&p&&(&/span&&span class=&n&&AF_INET&/span&&span class=&p&&,&/span& &span class=&n&&SOCK_STREAM&/span&&span class=&p&&,&/span& &span class=&mi&&0&/span&&span class=&p&&);&/span&
&span class=&c1&&// 把这个套接字句柄绑定到一个地址,如localhost:9000&/span&
&span class=&n&&bind&/span&&span class=&p&&(&/span&&span class=&n&&sockfd&/span&&span class=&p&&,&/span& &span class=&n&&servaddr&/span&&span class=&p&&,&/span& &span class=&k&&sizeof&/span&&span class=&p&&(&/span&&span class=&n&&servaddr&/span&&span class=&p&&));&/span&
&span class=&c1&&// 开始使用这个套接字监听,最大pending的连接数为100&/span&
&span class=&n&&listen&/span&&span class=&p&&(&/span&&span class=&n&&sockfd&/span&&span class=&p&&,&/span& &span class=&mi&&100&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&客户端也使用的套接字进行连接:&/p&&div class=&highlight&&&pre&&code class=&language-cpp&&&span&&/span&&span class=&c1&&// 客户端也是创建一个套接字&/span&
&span class=&kt&&int&/span& &span class=&n&&sockfd&/span& &span class=&o&&=&/span& &span class=&n&&socket&/span&&span class=&p&&(&/span&&span class=&n&&AF_INET&/span&&span class=&p&&,&/span& &span class=&n&&SOCK_STREAM&/span&&span class=&p&&,&/span& &span class=&mi&&0&/span&&span class=&p&&);&/span&
&span class=&c1&&// 用这个套接字连接到一个serveraddr&/span&
&span class=&n&&connect&/span&&span class=&p&&(&/span&&span class=&n&&sockfd&/span&&span class=&p&&,&/span& &span class=&n&&servaddr&/span&&span class=&p&&,&/span& &span class=&k&&sizeof&/span&&span class=&p&&(&/span&&span class=&n&&servaddr&/span&&span class=&p&&));&/span&
&span class=&c1&&// 向这个套接字发送数据&/span&
&span class=&n&&send&/span&&span class=&p&&(&/span&&span class=&n&&sockfd&/span&&span class=&p&&,&/span& &span class=&n&&sendline&/span&&span class=&p&&,&/span& &span class=&n&&strlen&/span&&span class=&p&&(&/span&&span class=&n&&sendline&/span&&span class=&p&&),&/span& &span class=&mi&&0&/span&&span class=&p&&);&/span&
&span class=&c1&&// 关闭连接&/span&
&span class=&n&&close&/span&&span class=&p&&(&/span&&span class=&n&&sockfd&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&也就是说TCP和UDP连接都是使用套接字创建的,所以WebSocket的名字就是这么来的,本质上它就是一个套接字,并变成了一个标准,浏览器器开放了API,让网页开发人员也能直接创建套接字和服务端进行通信,并且这个套接字什么时候要关闭了由你们去决定,而不像http一样请求完了浏览器或者服务器就自动把TCP的套接字连接关了。&/p&&p&所以说WebSocket并不是一个什么神奇的东西,它就是一个套接字。同时,WebSocket得借助于现有的网络基础,如果它再从头搞一套建立连接的标准代价就会很大。在它之前能够和服务连接的就只有http请求,所以它得借助于http请求来建立一个原生的socket连接,因此才有了协议转换的那些东西。&/p&&p&浏览器建立一个WebSocket连接非常简单,只需要几行代码:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// 创建一个套接字&/span&
&span class=&kr&&const&/span& &span class=&nx&&socket&/span& &span class=&o&&=&/span& &span class=&k&&new&/span& &span class=&nx&&WebSocket&/span&&span class=&p&&(&/span&&span class=&s1&&'ws://192.168.123.20:9090'&/span&&span class=&p&&);&/span&
&span class=&c1&&// 连接成功&/span&
&span class=&nx&&socket&/span&&span class=&p&&.&/span&&span class=&nx&&onopen&/span& &span class=&o&&=&/span& &span class=&kd&&function&/span& &span class=&p&&(&/span&&span class=&nx&&event&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&console&/span&&span class=&p&&.&/span&&span class=&nx&&log&/span&&span class=&p&&(&/span&&span class=&s1&&'opened'&/span&&span class=&p&&);&/span&
&span class=&c1&&// 发送数据&/span&
&span class=&nx&&socket&/span&&span class=&p&&.&/span&&span class=&nx&&send&/span&&span class=&p&&(&/span&&span class=&s1&&'hello, this is from client'&/span&&span class=&p&&);&/span&
&span class=&p&&};&/span&
&/code&&/pre&&/div&&p&因为浏览器已经按照文档实现好了,而要创建一个WebSocket的服务端应该怎么写呢?这里我们先抛开Chrome源码,先研究服务端的实现,然后再反过来看浏览器客户端的实现。准备用Node.js实现一个WebSocket的服务端,来研究整一个连接建立和接收发送数据的过程是怎么样的。&/p&&p&WebSocket已经在&a href=&https://link.zhihu.com/?target=https%3A//datatracker.ietf.org/doc/rfc6455/%3Finclude_text%3D1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&RFC 6455&/a&里面进行了标准化,我们只要按照文档的规定进行实现就能和浏览器进行对接,这个文档的说明比较有趣,特别是第1部分,有兴趣的读者可以看看,并且我们发现WebSocket的实现非常简单,读者如果有时间的话可以先尝试自己实现一个,然后再回过头来,对比本文的实现。&/p&&h2&1. 连接建立&/h2&&p&使用Node.js创建一个hello, world的http服务,如下代码index.js所示:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kd&&let&/span& &span class=&nx&&http&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s2&&&http&&/span&&span class=&p&&);&/span&
&span class=&kr&&const&/span& &span class=&nx&&hostname&/span& &span class=&o&&=&/span& &span class=&s2&&&192.168.123.20&&/span&&span class=&p&&;&/span& &span class=&c1&&// 或者}

我要回帖

更多关于 按键精灵源代码在哪里 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信