TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
开车了,也慢慢不规矩起来了,于是乎,违章信息也慢慢多起来了,但是无法第一时间通知到自己。
虽说,有个网站:
http://www.hzti.com/service/qry/violation_veh.aspx?pgid=&type=1&node=249
可以查询非现场违章情况,
不过:
1.我是懒人,主动去查询的时候不太乐意做
2.车辆识别码,永远记不住
3.每次输验证码,挺麻烦的
所以,我希望,只要有违规信息,能主动通知到我。
程序员嘛,自己动手,丰衣足食。 :)
实现思路:
1.爬取
http://www.hzti.com/service/qry/violation_veh.aspx?pgid=&type=1&node=249的信息
2.使用飞信命令发送短信消息(http://www.it-adv.net/)--免费的哦。
实现难点:
1.验证码破击
我对图片毫无研究,幸好它的验证码太简单了,只有#000000(黑色)才是验证码信息,其他的都是无用信息。并且元素的位置都是固定的。
2.网站用.net实现,在post信息的时候,有一陀无用的数据信息。所幸,post数据的时候,并没有对数据做加密,不然都挺难判断具体参数的意义
验证码破解思路:
1.自我学习:通过程序下载多张验证码图片,去噪点,切割图片元素,找出最清楚的0-9这10个元素图片。作为样本;
2.破解:下载需要破解的验证码图片,去噪点,切割图片元素,和样本像素比较,相似度在95%以上的视为一致。
得到图片信息并且去噪点的方法:
1
//
得到图片信息,去除噪点的图片
2
BufferedImage getBufferedImage(InputStream in)
throws
Exception {
3
BufferedImage img
=
ImageIO.read(in);
4
for
(
int
i
=
0
; i
<
img.getWidth(); i
++
) {
5
for
(
int
j
=
0
; j
<
img.getHeight(); j
++
) {
6
//
黑色的才是验证码
7
if
(
!
CODE_RGB.equals(Integer.toHexString(img.getRGB(i, j)))) {
8
img.setRGB(i, j,
-
1
);
9
}
10
}
11
}
12
in.close();
13
return
img;
14
}
得到图片像素信息(RGB值)
1
int
[][] getImageFeature(BufferedImage img)
throws
Exception {
2
int
[][] feature
=
new
int
[WIDTH][HEIGHT];
3
for
(
int
i
=
0
; i
<
WIDTH; i
++
) {
4
for
(
int
j
=
0
; j
<
HEIGHT; j
++
) {
5
if
(img.getWidth()
<
i
||
img.getHeight()
<
j) {
6
continue
;
7
}
8
feature[j]
=
img.getRGB(i, j);
9
}
10
}
11
return
feature;
12
}
下载多张图片,切割,保存,人工寻找最清晰的0-9这10个元素图片
public
void
learn(
int
count)
throws
Exception {
for
(
int
c
=
0
; c
<
count; c
++
) {
BufferedImage img
=
getBufferedImage(
new
URL(IMG_URL).openStream());
//
保存样本
for
(
int
i
=
1
; i
<
5
; i
++
) {
BufferedImage bi
=
img.getSubimage(i
*
X_BASE, Y_BASE, WIDTH, HEIGHT);
String name
=
String.valueOf(c)
+
"
_
"
+
String.valueOf(i);
ImageIO.write(bi, IMAGE_FORMAT,
new
File(IMG_REF
+
"
learn/
"
+
name
+
"
.bmp
"
));
}
}
}
备注:
GifImageWriter有bug。对于BufferedImage的subBufferedImage输出一直有问题。Sun很早就有人提交了bug,貌似还没有修复。
破解代码(说破解,有点汗。。。其实压根儿和破解没关系)
1
public
String crack(InputStream in)
throws
Exception {
2
BufferedImage img
=
getBufferedImage(in);
3
StringBuilder ret
=
new
StringBuilder();
4
5
for
(
int
c
=
1
; c
<
5
; c
++
) {
6
BufferedImage bi
=
img.getSubimage(c
*
X_BASE, Y_BASE, WIDTH, HEIGHT);
7
int
[][] feature
=
getImageFeature(bi);
8
9
for
(ImageCode ic : imageCodes) {
10
int
success
=
0
;
11
for
(
int
i
=
0
; i
<
WIDTH; i
++
) {
12
for
(
int
j
=
0
; j
<
HEIGHT; j
++
) {
13
if
(feature[j]
==
ic.getFeature()[j]) {
14
success
++
;
15
}
16
}
17
}
18
//
判断是否匹配上
19
if
(success
*
100.0
/
(WIDTH
*
HEIGHT)
>
95
) {
20
ret.append(ic.getCode());
21
22
continue
;
23
}
24
}
25
26
}
27
28
return
ret.toString();
29
}
其中,imageCodes是初始化准备的0-9这10个元素图片的特征信息和对应的值
之后的事情就简单了。通过LiveHttpHeader找到Post提交的数据,通过shell脚本,模拟。搞定。
主要用到curl命令
1
curl
-
b
"
ASP.NET_SessionId=$SESSION_ID
"
"
$IMAGE_CODE_URL
"
-
o
$TMP_CODE_BASE
2
code
=
`java
-
cp lib
/
traffic
.
jar TrafficImgCracker
$TMP_CODE_BASE
`
3
6
curl
-
A
"
$AGENT
"
-
e
$TRAFFIC_URL
-
b
"
ASP.NET_SessionId=$SESSION_ID;isLoginedWeb=T;ImageV=$code
"
-
d
"
$QUERY_PARAM
"
"
$TRAFFIC_URL
"
-
o
$TMP_CONTENT_BASE
7
8
now
=
`cat
$TMP_CONTENT_BASE
|
grep
-
r
"
<td class="xxcxsspoptds">
"
|
sed
"
s/<[^>]*>//g
"
|
sed
"
s/s+/ /g
"
`
9
his
=
`cat
$HIS_CONTENT_BASE
|
grep
-
r
"
<td class="xxcxsspoptds">
"
|
sed
"
s/<[^>]*>//g
"
|
sed
"
s/s+/ /g
"
`
10
11
if
[
"
$now
"
!=
"
$his
"
];then
12
msg
=
`cat
$TMP_CONTENT_BASE
|
grep
-
r
"
<td class="xxcxsspoptds">
"
|
sed
"
s/<[^>]*>//g
"
|
sed
"
s/s+/ /g
"
|
head
-
n
6
`
13
echo
$msg
14
#
send
15
fi
shell一直不熟,代码估计挺猥琐的。。。
最后通过飞信命令发送消息:
1
$FETION_HOME
/
fetion
--
mobile
=
12345678901
--
pwd
=
bugaosuni
--
to
=
12345678901
--
msg
-
utf8
=
"
$msg
"
广告下:
飞信命令行,挺好的东东,像系统报警等,都能考虑用它来完成。
最后,附上图片破解的代码:
1
import
java.awt.image.BufferedImage;
2
import
java.io.File;
3
import
java.io.FileInputStream;
4
import
java.io.InputStream;
5
import
java.net.URL;
6
import
java.util.ArrayList;
7
import
java.util.List;
8
9
import
javax.imageio.ImageIO;
10
11
/**
12
* 交通网图片分析工具
13
*
14
*
@author
<a href="mailto:li.jinl@alibaba-inc.com">Stone.J</a> 2010-10-10
15
*/
16
public
class
TrafficImgCracker {
17
18
private
static
final
String IMG_URL
=
"
http://www.hzti.com/government/CreateCheckCode.aspx
"
;
19
private
static
final
String IMG_REF
=
"
/home/stone/tmp/imgref/
"
;
20
21
private
static
final
int
X_BASE
=
9
;
22
private
static
final
int
Y_BASE
=
0
;
23
private
static
final
int
WIDTH
=
7
;
24
private
static
final
int
HEIGHT
=
22
;
25
private
static
final
String IMAGE_FORMAT
=
"
bmp
"
;
26
private
static
final
String CODE_RGB
=
"
ff000000
"
;
27
28
private
List
<
ImageCode
>
imageCodes
=
new
ArrayList
<
ImageCode
>
(
10
);
29
30
public
static
void
main(String[] args)
throws
Exception {
31
if
(args.length
!=
1
) {
32
System.out.println(
"
java TrafficImgCracker $file_path
"
);
33
System.exit(
1
);
34
}
35
36
String file
=
args[
0
];
37
38
TrafficImgCracker cracker
=
new
TrafficImgCracker();
39
cracker.init();
40
System.out.print(cracker.crack(file));
41
}
42
43
/**
44
* init
45
*
46
*
@throws
Exception
47
*/
48
public
void
init()
throws
Exception {
49
File ref
=
new
File(IMG_REF);
50
File[] files
=
ref.listFiles();
51
for
(File f : files) {
52
if
(
!
f.isFile()) {
53
continue
;
54
}
55
String code
=
f.getName().substring(
0
, f.getName().indexOf(
"
.
"
));
56
BufferedImage img
=
getBufferedImage(
new
FileInputStream(f));
57
int
[][] feature
=
getImageFeature(img);
58
//
add to image codes
59
imageCodes.add(
new
ImageCode(code, feature));
60
}
61
}
62
63
/**
64
* crack
65
*
66
*
@param
file
67
*
@return
68
*
@throws
Exception
69
*/
70
public
String crack(String file)
throws
Exception {
71
return
crack(
new
FileInputStream(file));
72
}
73
74
/**
75
* crack image code
76
*
77
*
@param
in image input stream
78
*
@return
code
79
*/
80
public
String crack(InputStream in)
throws
Exception {
81
BufferedImage img
=
getBufferedImage(in);
82
StringBuilder ret
=
new
StringBuilder();
83
84
for
(
int
c
=
1
; c
<
5
; c
++
) {
85
BufferedImage bi
=
img.getSubimage(c
*
X_BASE, Y_BASE, WIDTH, HEIGHT);
86
int
[][] feature
=
getImageFeature(bi);
87
88
for
(ImageCode ic : imageCodes) {
89
int
success
=
0
;
90
for
(
int
i
=
0
; i
<
WIDTH; i
++
) {
91
for
(
int
j
=
0
; j
<
HEIGHT; j
++
) {
92
if
(feature[j]
==
ic.getFeature()[j]) {
93
success
++
;
94
}
95
}
96
}
97
//
判断是否匹配上
98
if
(success
*
100.0
/
(WIDTH
*
HEIGHT)
>
95
) {
99
ret.append(ic.getCode());
100
101
continue
;
102
}
103
}
104
105
}
106
107
return
ret.toString();
108
}
109
110
/**
111
* learn
112
*
113
*
@param
count learning count
114
*
@throws
Exception
115
*/
116
public
void
learn(
int
count)
throws
Exception {
117
for
(
int
c
=
0
; c
<
count; c
++
) {
118
BufferedImage img
=
getBufferedImage(
new
URL(IMG_URL).openStream());
119
//
保存样本
120
for
(
int
i
=
1
; i
<
5
; i
++
) {
121
BufferedImage bi
=
img.getSubimage(i
*
X_BASE, Y_BASE, WIDTH, HEIGHT);
122
String name
=
String.valueOf(c)
+
"
_
"
+
String.valueOf(i);
123
ImageIO.write(bi, IMAGE_FORMAT,
new
File(IMG_REF
+
"
learn/
"
+
name
+
"
.bmp
"
));
124
}
125
}
126
}
127
128
//
得到图片信息,去除噪点的图片
129
private
BufferedImage getBufferedImage(InputStream in)
throws
Exception {
130
BufferedImage img
=
ImageIO.read(in);
131
for
(
int
i
=
0
; i
<
img.getWidth(); i
++
) {
132
for
(
int
j
=
0
; j
<
img.getHeight(); j
++
) {
133
//
黑色的才是验证码
134
if
(
!
CODE_RGB.equals(Integer.toHexString(img.getRGB(i, j)))) {
135
img.setRGB(i, j,
-
1
);
136
}
137
}
138
}
139
in.close();
140
return
img;
141
}
142
143
//
得到图片特征
144
private
int
[][] getImageFeature(BufferedImage img)
throws
Exception {
145
int
[][] feature
=
new
int
[WIDTH][HEIGHT];
146
for
(
int
i
=
0
; i
<
WIDTH; i
++
) {
147
for
(
int
j
=
0
; j
<
HEIGHT; j
++
) {
148
if
(img.getWidth()
<
i
||
img.getHeight()
<
j) {
149
continue
;
150
}
151
feature[j]
=
img.getRGB(i, j);
152
}
153
}
154
return
feature;
155
}
156
157
/**
158
* image code bean
159
*
160
*
@author
<a href="mailto:li.jinl@alibaba-inc.com">Stone.J</a> 2010-10-10
161
*/
162
public
static
class
ImageCode {
163
164
private
String code;
165
private
int
[][] feature;
166
167
public
ImageCode(String code,
int
[][] feature){
168
this
.code
=
code;
169
this
.feature
=
feature;
170
}
171
172
public
String getCode() {
173
return
code;
174
}
175
176
public
void
setCode(String code) {
177
this
.code
=
code;
178
}
179
180
public
int
[][] getFeature() {
181
return
feature;
182
}
183
184
public
void
setFeature(
int
[][] feature) {
185
this
.feature
=
feature;
186
}
187
}
188
189
}
源码下载:http://file.javaxxz.com/2014/10/28/235546781.zip |
|