编程

1
2
3
4
5
6
7
8
**---------------|相关学习资源|---------------**
二进制安全相关工具和教程站点
http://www.openrce.org
http://www.ollydbg.de
http://www.sysersoft.com
http://www.idapro.com
http://www.woodmann.com
http://www.hex-rays.com IDA pro
1
2
3
4
5
6
7
**---------------|二进制基础知识|---------------**
CPU指令的基本单位
1 byte = 8 bit
1 word = 2 byte
1 double word = 2 word
1 kilobyte = 1024 byte
1 megabyte = 1024 kbyte = 1024*1024 byte = 1048576 byte
1
2
3
4
5
6
7
8
9
10
11
**---------------|汇编语言基础知识|---------------**
**寄存器**
80386处理器中的寄存器分为8组,每组宽度为32位
*通用寄存器
*段寄存器
*指令寄存器
*标志寄存器
*系统地址寄存器
*控制寄存器
*调试寄存器
*测试寄存器

通用寄存器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
EAX	累加器
EBX 基址寄存器
ECX 计数器
EDX 数据寄存器
ESI 源变址寄存器
EDI 目的变址寄存器
EBP 扩展基址指针寄存器
ESP 栈指针寄存器


EAX EBX ECX EDX ESI EDI EBP ESP #32位
AX BX CX DX SI DI BP SP #低16位
AH BH CH DH #高8位
AL BL CL DL #低8位

段寄存器:

1
2
3
4
5
6
CS:代码段(Code Segment)
DS:数据段(Data Segment)
ES:附加数据段(Extra Segment)
SS:堆栈段(Stack Segment)
FS:附加段
GS 附加段

指令寄存器:
EIP 指令指针寄存器
低16位为IP(8086)
它存储的是下一条要执行指令的地址。

标志寄存器:

1
2
3
4
5
6
7
8
9
10
11
12
13
IOPL(I/O Privilege Level)	I/O特权级字段,它的宽度为2bit,它指定了I/O指令的特权级。如果当前的特权级别在数值上小于或等于IOPL,那么I/O指令可执行。否则,将发生一个保护性异常。
NT(Nested Task): 控制中断返回指令IRET,它宽度为1位。NT=0,用堆栈中保存的值恢复EFLAGS,CS和EIP从而实现中断返回;NT=1,则通过任务切换实现中断返回。
RF(Restart Flag): 重启标志,它的宽度是1位。它主要控制是否接受调试故障。RF=0接受,RF=1忽略。如果你的程序每一条指令都被成功执行,那么RF会被清0。而当接受到一个非调试故障时,处理器置RF=1。
VM(Virtual Machine): 虚拟8086模式(用软件来模拟8086的模式,所以也称虚拟机)。VM=0,处理器工作在一般的保护模式下;VM=1,工作在V8086模式下。
其它16个标志位的含义和8086一样:
CF(Carry Flag): 进位标志位,由CLC,STC两标志位来控制
PF(Parity Flag): 奇偶标志位
AF(Assistant Flag): 辅助进位标志位
ZF(Zero Flag): 零标志位
SF(Singal Flag): 符号标志位
IF(Interrupt Flag): 中断允许标志位,由CLI,STI两条指令来控制
DF(Direction Flag): 向量标志位,由CLD,STD两条指令来控制
OF(Overflow Flag): 溢出标志位

寻址方式
段基址*10H+段内偏移地址,形成20位地址
段基址是16的倍数,长度最大不超过64K

站点地图这个东西,目的是为了对搜索引擎友好。搜索引擎每天来爬你的网站,如果能给它提供一份实时更新的站点地图,自然会让搜索引擎在爬取网站的时候更加有效率。

这里用php实现了一个自动化的站点地图生成器,可以在爬虫访问站点地图的时候动态的创建页面,来提供一份实时更新的sitemap.xml。
具体的实现,首先你需要让apache服务器支持将xml文件作为php来解析,这样sitemap.xml中的php语句得以执行。
可在站点根目录下的.htaccess文件的<IfModule mod_rewrite.c>和</IfModule>之间加入这一句:

1
AddType application/x-httpd-php .xml

至于php部分,其实就是先获取网站首页所有的url,再将url写入页面,同时将创建的日期设为今天。这样爬虫就会认为站点是实时更新的,从而提高搜索排名。
然后就是sitemap.xml的源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php
error_reporting(0);//禁止报错
header("Content-type:text/xml"); //输出xml作为文档的头部
echo '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.chorder.net">';

function _getUrlContent($url) {
$handle = fopen($url, "r");
if ($handle) {
$content = stream_get_contents($handle, 1024 * 1024);
return $content;
} else {
return false;
}
}

function _filterUrl($web_content) {
$reg_tag_a = '/<[a|A].*?href=[\'\"]{0,1}([^>\'\"\ ]*).*?>/';
$result = preg_match_all($reg_tag_a, $web_content, $match_result);
if ($result) {
return $match_result[1];
}
}

function _reviseUrl($base_url, $url_list) {
$url_info = parse_url($base_url);
$base_url = $url_info["scheme"] . '://';
if ($url_info["user"] && $url_info["pass"]) {
$base_url .= $url_info["user"] . ":" . $url_info["pass"] . "@";
}
$base_url .= $url_info["host"];
if ($url_info["port"]) {
$base_url .= ":" . $url_info["port"];
}
$base_url .= $url_info["path"];
if (is_array($url_list)) {
foreach ($url_list as $url_item) {
if (preg_match('/^http/', $url_item)) {
$result[] = $url_item;
} else {
$real_url = $base_url . '/' . $url_item;
$result[] = $real_url;
}
}
return $result;
} else {
return;
}
}

function crawler($url) {
$content = _getUrlContent($url);
if ($content) {
$url_list = _reviseUrl($url, _filterUrl($content));
if ($url_list) {
return $url_list;
} else {
return ;
}
} else {
return ;
}
}

function main() {
$current_url = "https://chorder.net";
$result_url_arr = crawler($current_url);
if ($result_url_arr) {
foreach ($result_url_arr as $url) {
echo '
<url>
<loc>'.$url.'</loc>
<lastmod>'.date("Y/m/d").'</lastmod>
<changefreq>always</changefreq>
<priority>1.0</priority>
</url>
';
}
}
echo '</urlset>';
}
main();
?>

效果可以见 https://chorder.net/sitemap.xml

一直想给安装一个缩略图点击弹出的插件,但是找了找几乎都是用的php来做的,插件的使用和安装极其繁琐,于是上网查了些demo,自己实现了一个纯js的图片弹出插件。

实现的思路是通过编写hook图片的onclick事件的函数,在函数中对body追加div元素,再将传入的图片对象放入元素中,同时再监听div的onclilck事件,当捕捉到点击,再关闭(其实是隐藏)弹出的div。
通过在函数初始化的时候收集页面所有的img元素,再为每个img元素增加onclick=”picHook(this)”这条属性,这样当图片在被点击时,这个函数就能自动创建div蒙板背景,并获取被点击图片的宽度和高度,同时生成一个新的和图片一样大小的div来显示图片。当蒙板再次被点击时,hook事件再次响应,并将蒙板和图片div的style置为none,弹出的图片就被关闭了。
实现效果见本博客,任意点击一个图片即可查看效果。
说起来很简单,做起来就更简单了,简单到只需要一个函数即可实现。
talking is cheap,show you my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<script>
function picHook(pic){
/*图片对象*/
var imgs = document.getElementsByTagName("img");
/*前景div*/
var light = document.getElementById('light') || document.createElement("div");
/*背景div*/
var bg = document.getElementById('bg') || document.createElement("div");
/*图片放大*/
var s_pic = document.getElementById('s_pic') || document.createElement("img");
/*css对象*/
var css = document.createElement("style");
/*css样式*/
var csstext = '\
.pic_bg{\
position: absolute;\
margin:0 auto; \
top: 0%;\
left: 0%;\
right: 0%;\
width: 100%;\
padding-bottom: 1000%;\
background-color: black;\
z-index:1001;\
opacity:.80;\
filter: alpha(opacity=80);\
overflow:scroll;\
}\

.pic_div {\
margin-bottom: auto;\
position: fixed;\
left:30%;\
top:20%;\
width: 100%;\
padding-top:25px;\
margin-left:-250px;\
margin-top:-100px;\
z-index:1002;\
}';
/*收集页面所有图片对象*/
for(i=0; i<imgs.length;i++){
imgs[i].setAttribute("onclick", "picHook(this)" );
}
css.type = "text/css";

/*关闭图像*/
if( !pic ){
bg.style.display = light.style.display = "none";
}

/*ie兼容*/
if(css.styleSheet){
css.styleSheet.cssText = csstext;
}else{
css.appendChild(document.createTextNode(csstext));
}

s_pic.setAttribute("id", "s_pic");
s_pic.setAttribute("src", pic.src);
s_pic.setAttribute("width","70%");
s_pic.setAttribute("height","65%");
s_pic.setAttribute("margin","0 auto");
s_pic.style.display = 'block';
light.setAttribute("id", "light");
light.setAttribute("class", "pic_div");
light.style.display = 'block';
light.appendChild(s_pic);
light.setAttribute("onclick", "picHook()");
bg.setAttribute("id", "bg");
bg.setAttribute("class", "pic_bg");
bg.setAttribute("onclick", "picHook()");
bg.style.display = light.style.display;
document.getElementsByTagName("head")[0].appendChild(css);
document.body.appendChild(bg);
document.body.appendChild(light);
}
</script>

将这段代码保存在页面的head中,再将body的onload事件绑定到picHook()函数,你的页面中就也可以实现图片点击弹出大图啦。
还存在一点小bug,主要是因为我不太熟悉css,导致div的样式做的有点难看。
css的样式我是直接声明在js里的,这样就不用再另外创建css文件了。
强迫症,没办法。
等有时间再琢磨琢磨css,优化下样式。
喜欢就拿去吧。
你可以点击下面的图片测试一下看看效果:

有了Ruby笔记,怎么能少了python笔记呢。
这里主要记录我的python使用心得和调错笔记。

No module named win32api
安装pywin32
进入这个链接:

http://sourceforge.net/projects/pywin32/
http://sourceforge.net/projects/pywin32/files/pywin32/Build%20220/

选择对应的版本,例如64位windows,python版本2.7.1,则选择

pywin32-220.win-amd64-py2.7.exe

Python比较难找的cffi包

1
pypi.python.org/packages/source/c/cffi/cffi-1.4.2.tar.gz

定义类
定义类的过程就是定义类的属性的过程;
类的属性就是累的静态属性的简称,指类内包含的各项数据。

类的服务被称为成员函数或方法。

继承extends
通过定义继承方法,子类可以获得父类的所有属性和方法

接口implements
说明当前类中实现了哪个接口定义的功能和方法
是Java语言中实现多重继承的一种机制

类的修饰符分为:
访问控制符
抽象类说明符
最终说明符

类的属性:
描述了类内部的信息,又称为类的静态属性
类属性为简单变量

【修饰符】 变量类型 变量名【=变量初值】
【修饰符】 类名 对象名 【=new 类名(实际参数列表)】

若使用另一个类的对象作为当前类所定义的类的属性,
要保证该对象所在的类在当前类中是可已被当前类所引用的

类属性的修饰符包括:
访问控制符
静态修饰符static
最终修饰符final
易失修饰符volatile
过渡丢师傅transient

类的方法(成员函数)
用来规定类属性上的操作
实现类内部功能的机制
也是类与外界交互的窗口

声明方法的语法:
【修饰符】返回值类型 方法名(参数列表)
Trows 例外名1,例外名2,…
{
方法体:
局部变量声明;
语句序列;
}

方法的修饰符包括:
访问控制符
静态修饰符static
抽象修饰符abstract
最终修饰符final
同步修饰符synchronous
本地修饰符native

类的构造函数

特殊之处:
构造函数的方法名与类名相同
构造函数没有返回类型
构造函数的主要作用是完成对类对象的初始化工作

在创建一个类的新对象的同时,系统会自动调用该类的构造函数为新对象初始化

Java在声明类是,可以不定义构造函数,系统会自动为该类生成一个默认的构造函数
此时这个构造函数的名字与类名相同,没有任何形式参数,也不完成任何操作

类的访问控制符只有一个public
属性和方法的访问控制符有:
public

private
protected
private protected

对于同一个包中的类可以不需任何说明,方便的互相访问和引用

在不同包中的类,只有他们都声明为public时,然后再在程序头部声明import后才可以被访问和引用相应的类。

publici修饰的类的属性称为公共属性
如果公共属性属于一个公共类,则可以被所有的其他类使用

public修饰符会造成安全性和数据封装性下降,应尽量减少public属性的使用

缺省访问控制符规定该类只能被同一个包中的类访问和引用,而不可以被其他包中的类引用,这种特性称为包访问性。

类内的属性和方法如果没有访问控制符来限定,也说明他们具有包访问性,可以被同一个包中的其他类所访问和调用

用private修饰的属性或方法只能被该类自身所访问和修改,而不能被任何其他类,包括该类的子类来获取和引用。
procted修饰的属性可以被该类自身和包中的类访问
public可以被任意访问

静态属性
被static修饰的属性称为静态属性
静态属性是一个公共的存储单元
任何一个类的对象访问它时取到的都是相同的值
任何一个类的对象去修改它时,都是在对同一个内存单元做操作。

static修饰符修饰的属性是属于类的公共属性
static修饰符修饰的方法是属于整个类的方法
不用static修饰符修饰的方法是属于某个具体对象或实例的方法

声明一个方法的static至少有三重含义
调用这个方法时,应该使用类名做前缀,而不是某一个具体的对象名
非static的方法是属于某个对象的方法,在这个对象创建时对象的方法在内存中拥有自己的专用代码段
而static的方法是属于整个类的
它在内存中的代码段将随着类的定义而分配和装载,不被任何一个对象专有
static方法只能处理static类型的数据

静态初始化器
石油关键字static引导的一对大括号括起的语句组

静态初始化器与构造函数的区别:
构造函数是对每个新创建的对象初始化,而静态初始化器是对每个类进行初始化
构造函数是在用new运算符产生新对象时由系统自动执行,而静态初始化器则是在它所属的类加载入内存时由系统调用运行的
不同于构造函数,静态初始化器不是方法,没有方法名,返回值和参数列表

抽象类
当一个类被生命为abstract时,这个类被称为抽象类
所谓抽象类就是没有具体实例对象的类
抽象类是它所有子类的公共属性的集合
使用抽象类的一大优点就是可以利用这些公共属性来提高开发和维护程序的效率

最终类,最终属性,最终方法,终结器
最终类
如果一个类被final修饰符所修饰和限定,说明这个类不可能拥有子类
最终属性
final就是用来修饰常量的修饰符,一个类的成员变量如果被声明为final,那么它的取值在程序的执行过程中都不会改变,也就是一个常量

用final修饰符说明常量时:
需要说明常量的数据类型
需要同时指出常量的具体取值
因为所有类的对象的常量成员,其数值都固定一致,为了节省空间,常量通常都被声明为static

final修饰符所修饰的类方法,是功能和内部语句都不能被更改的最终方法,即是不能被当前类的子类重载的方法
final方法固定所对应的具体操作,防止子类对父类关键方法的错误的重定义,保证了程序的安全性和正确性

所有已被private修饰符限定为私有的方法,以及所包含在final类中的方法,都被缺省的认为是final的

终结器
终结器是回收对象时执行的方法
protected void finalize(){}
终结器是一个名为finalize的方法,没有产生列表和返回值

volatile修饰符
被volatile修饰的类的属性可能同时被几个线程控制和修改
通常用来修饰受外部输入的属性

建立热点:

1
2
3
4
@echo off
netsh wlan set hostednetwork mode=allow
netsh wlan set hostednetwork ssid=热点名 key=密码
netsh wlan start hostednetwork

关闭热点

1
netsh wlan set hostednetwork mode=disallow

win10上搭建raby on rails环境:
步骤如下

1.安装ruby (我选择的版本是ruby 2.2.3p173)
2.安装rails gem
在这之前建议先把gem的源换成淘宝的源,速度快点。

1
2
3
4
5
6
7
$ gem sources --add https://ruby.taobao.org/ --remove https://rubygems.org/
$ gem sources -l
*** CURRENT SOURCES ***

https://ruby.taobao.org
# 请确保只有 ruby.taobao.org
$ gem install rails

之后:

1
2
gem install rails
gem install bundler

3.安装devkit
下载地址;

http://rubyinstaller.org/downloads

如果是win10,选择DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe这个版本的。
然后运行,将程序解压到c:\devkit
进入c:\devkit目录

1
ruby dk.rb init

之后修改config.yml
添加下面三行

1
2
3
---
- C:/Ruby22-x64
- C:/Ruby22-x64

注意把路径换成当前ruby的安装路径,-前后各有一个空格不可忽略。
然后:

1
ruby dk.rb install

最后进入需要建立工程的目录,使用如下命令新建rails项目

1
rails new testapp

如果在此过程中报错,则进入testapp中
使用

1
bundler install

来安装所需要的依赖包。
如果还报错,修改testapp目录中的Gemfile
将第一行的sources源内容改为

1
source 'https://ruby.taobao.org/'

然后再执行bundler install命令

Debian中搭建ruby on rails开发环境
假设你已经安装好ruby了
接下来安装rvm

1
$ curl -L https://get.rvm.io | bash -s stable

某些情况下,可能需要编译一下rvm的初始化脚本
我的位置是在/etc/profile.d/rvm.sh,所以运行这一句:

1
$source /etc/profile.d/rvm.sh

接着安装bundler

1
gem install bundler

然后安装rails

1
gem install rails

如果这地方出现错误,尝试使用rvm切换ruby的版本:

1
2
rvm install 2.0.0
rvm 2.0.0 --default

CentOS中搭建ruby on rails开发环境

1
2
3
4
5
6
$curl -L https://get.rvm.io | bash -s stable
$source /usr/local/rvm/bin/rvm
$rvm install 2.0.0
$rvm 2.0.0 --default
$gem install bundler
$gem install rails

python:
先按F5,之后将下面的命令保存,再设置快捷键。

1
cmd /k  c:\python27\python "$(FULL_CURRENT_PATH)" & PAUSE & EXIT

我使用的是Ctrl+F9
之后按Ctrl+s保存更改,再按Ctrl+F7即可快速在cmd中运行代码,方便调试。

ruby

1
cmd /k  C:\Ruby22-x64\bin\ruby "$(FULL_CURRENT_PATH)" & PAUSE & EXIT

1.数组遍历方法总结
(1)

1
array = (1..10).to_a 

(2)

1
2
3
4
5
length = array.length 
length.times do t
print "#{array[t]} "
end
puts "n"

(3)

1
2
3
4
5
length = array.length-1 
for i in 0..length do
print "#{array[i]} "
end
puts "n"

(4)

1
2
3
4
5
6
7
8
9
for i in array do 
print "#{i} "
end
puts "n"
```Ruby
(5)
```Ruby
array.each{x print x," "}
puts "n"

(6)

1
2
3
4
5
6
7
length = array.length 
i = 0
while i< length do
print "#{array[i]} "
i = i+1
end
puts "n"

(7)

1
2
3
4
5
6
7
length = array.length 
i = 0
until i==length do
print "#{array[i]} "
i += 1
end
puts "n"

(8)

1
2
array.each_index do i 
print "#{array[i]} "

2.Ruby连接数据库
(1).mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
require 'mysql'  
begin
db = Mysql.init
db.options(Mysql::SET_CHARSET_NAME, 'utf8')
db = Mysql.real_connect("127.0.0.1", "root", "123456", "test", 3306)
db.query("SET NAMES utf8")
db.query("drop table if exists tb_test")
db.query("create table tb_test (id int, text LONGTEXT) ENGINE=MyISAM DEFAULT CHARSET=utf8")
db.query("insert into tb_test (id, text) values ( 1,'first line'),(2,'second line')")
printf "%d rows were inserted\n",db.affected_rows
rslt = db.query("select text from tb_test")
while row = rslt.fetch_row do
puts row[0]
end
rescue Mysql::Error => e
puts "Error code: #{e.errno}"
puts "Error message: #{e.error}"
puts "Error SQLSTATE: #{e.sqlstate}" if e.respond_to?("sqlstate")
ensure
db.close if db
end

(2).redis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/ruby

require 'redis'

def writeToFile(file,content)
fp = File.new(file,"a+")
if fp
fp.syswrite(content)
else
puts "..."
end
end

def connect(host)
redis = Redis.new(:host => host,:port => 6379)
redis.info.keys.each do |key|
puts "#{key}:\t"+redis.info["#{key}"]
end
end

connect("1.1.1.1")

(3).sqlite3

1
2
3
4
5
6
7
8
9
10
11
12
require 'sqlite3'

db = SQLite3::Database.new('test.db')

db.execute("create table test(
ID integet not null,
Username varchar(20) null,
Password varchar(64) null)")
db.execute("insert into test(ID.Username,Password)
values('0','admin','admin')")
db.execute("select * from test")
db.execute("update test set password='12345' where id=0")

3.Ruby socket
服务端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
require 'socket'

server = TCPServer.open('0.0.0.0', 8080)
loop do
Thread.start(server.accept) do |client|
begin
while true
puts "#{client.to_i} online"
data = client.read()
throw "empty" if data.empty?
#puts data.length
puts data
end
rescue Exception => e
puts "#{client.to_i} offline"
end
end
end

客户端:

1
2
3
4
5
6
7
8
9
require 'socket'

hostname = '127.0.0.1'
port = 8080
buf = 'test'
s = TCPSocket.open(hostname, port)
s.write buf
sleep(1)
s.close

4.ruby gem 文档
rubygems.org上main的gem文档访问起来太慢了,其实装了gem的机器本身就自带doc的功能
使用下列命令可以启动gem自带的文档

1
gem server --port 1234

然后用浏览器访问http://localhost:1234就可以查看相关的gem文档。

5.ruby改变控制台输出内容的颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
puts "\033[1m前景色\033[0m\n"  
puts "\033[30mBlack (30)\033[0m\n"
puts "\033[31mRed (31)\033[0m\n"
puts "\033[32mGreen (32)\033[0m\n"
puts "\033[33mYellow (33)\033[0m\n"
puts "\033[34mBlue (34)\033[0m\n"
puts "\033[35mMagenta (35)\033[0m\n"
puts "\033[36mCyan (36)\033[0m\n"
puts "\033[37mWhite (37)\033[0m\n"
puts ''
puts "\033[1m背景色\033[0m\n"
puts "\033[40m\033[37mBlack (40), White Text\033[0m\n"
puts "\033[41mRed (41)\033[0m\n"
puts "\033[42mGreen (42)\033[0m\n"
puts "\033[43mYellow (43)\033[0m\n"
puts "\033[44mBlue (44)\033[0m\n"
puts "\033[45mMagenta (45)\033[0m\n"
puts "\033[46mCyan (46)\033[0m\n"
puts "\033[47mWhite (47)\033[0m\n"
puts ''
puts "\033[1m其他\033[0m\n"
puts "Reset (0)"
puts "\033[1mBold (1)\033[0m\n"
puts "\033[4mUnderlined (4)\033[0m\n"

6.一些比较特别的包
Ruby json gem
https://rubygems.global.ssl.fastly.net/gems/json-1.8.3.gem
树莓派wiringpi gpio包
http://pi.gadgetoid.com/article/wiringpi-as-a-ruby-gem

7.安装rvm的正确姿势
参考自:http://rvm.io/rvm/install
首先添加gpg公钥:

1
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

安装稳定版本的rvm

1
curl -sSL https://get.rvm.io | bash -s stable --ruby
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×