• 自己写的一个 hacker.org 模板


    在人人上看到好多大牛在刷hacker.org,打开看也不知道怎么玩,后来Su_Xing老祖告诉了我hacker.org的玩法:

    Challenge是各种类型的小谜题闯关,跟那些解密闯关的网页游戏类似,需要很广泛的知识

    Bot Wars貌似是写AI的,暂时还没有研究过

    Puzzles就是一些小游戏,这些游戏在网页源码里可以得到相应的游戏信息,把信息抓取出来,然后一番计算之后把答案在URL后面贴出来就可以到达后面一关,下面主要说的就是这个了

    这些小游戏可以通过搜索来解决,但是越往后面越是复杂,就需要很好的算法,是很好的练习搜索能力的题目。相比ACM而言,这个的限制更为宽松,你可以不择手段,什么多线程都可以用,甚至可以搭载几台电脑并行去算,只要能把答案算出来就Ok了,也不限制时间和内存。

    抓取信息和回馈答案都可以用脚本轻松实现,但是脚本的运行速度相比C/C++而言慢了不是一个数量级,所以我用前两天学的socket,将脚本抓取出来的信息发送到C++程序中,运算之后再发送回去,这样的方法写了一个模板:

     1 import urllib2
    2 import socket
    3 import re
    4
    5 game = 'XXXX'
    6 name = 'XXXX'
    7 pswd = 'XXXXXX'
    8 url = 'http://www.hacker.org/%s/index.php?name=%s&password=%s' % (game, name, pswd)
    9
    10 print url
    11
    12 def read(_url):
    13 content = urllib2.urlopen(_url).read()
    14 flavars = re.compile('FlashVars=".*"').search(content).group()[11:-1]
    15 return flavars
    16
    17 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    18 sock.connect(("127.0.0.1",5002))
    19
    20 nextl = url
    21 while True:
    22 case = read(nextl)
    23 print case
    24
    25 sock.send(case)
    26 ans = sock.recv(1024)
    27 ans = re.compile('[^\0]*').search(ans).group()
    28 print ans
    29
    30 nextl = url + '&path=' + ans

    这是抓取的python脚本模板,需要安装py环境,稍微解释下代码:

    5,6,7三行是要修改的内容,游戏名称,你的帐号和密码

    8链接得到要发送的URL

    12行的函数是发送URL,并在返回的html代码中取出FlashVars中的游戏关卡信息

    17,18是初始化socket

    20行之后就是主循环了,读取case,发送case,接收得到的答案字符串,1024是大小,接受的大小要根据不同谜题而修改,这里可以改的大一些,因为python的字符串不是以'\0'结束的,所以还要对ans进行处理,不然会返回404,然后连接得到下一关的URL

    30行,连接URL时候要注意,有些谜题是"&path=",有些是"&sol=",还有别的,这个地方根据需要做相应的修改

    然后在你要写的C++程序中加入下面一段:

     1 //your include
    2 #include<winsock.h>
    3
    4 SOCKET mysock;
    5 void _init(){
    6 SOCKET id;
    7 WSADATA wsaData;
    8 SOCKADDR_IN addr;
    9
    10 if(WSAStartup(MAKEWORD(2,0),&wsaData)){
    11 printf("Socket Error!");
    12 return;
    13 }
    14
    15 id = socket(AF_INET, SOCK_STREAM, 0);
    16 memset(&addr, 0, sizeof(addr));
    17 addr.sin_family = AF_INET;
    18 addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    19 addr.sin_port = htons(5002);
    20 bind(id, (sockaddr *)&addr, sizeof(addr));
    21
    22 listen(id, 1);
    23
    24 SOCKADDR_IN Client;
    25 int len = sizeof(SOCKADDR);
    26
    27 mysock = accept(id,(SOCKADDR *)&Client,&len);
    28 }
    29
    30 char msg[1024];
    31 void _send(){
    32 memset(msg,0,sizeof(msg));
    33
    34 //把你得到的答案转化成要求的字符串
    35
    36 send(mysock,msg,1024,0);
    37 }
    38
    39 void _recv(){
    40 recv(mysock, msg, 1024,0);
    41 puts(msg);
    42
    43 //把msg字符串转化为你需要的变量值
    44 }
    45
    46 int main(){
    47 _init();
    48
    49 while(true){
    50 _recv();
    51
    52 //运算得到答案
    53
    54 _send();
    55 }
    56
    57 return 0 ;
    58 }

    我使用的编译器是MinGW,如果你使用的其他编译器,需要对其中的头文件进行相应修改,MinGW在连接时需要添加 -lwsock32 的控制项,_send() 和 _recv() 中的发送大小以及字符串 msg[] 的大小根据不同游戏做不同的修改,最好能保持一致,并和py中的相同。

    由于C++代码是服务端,所以使用时先运行C++程序,然后再运行py程序。由于是自己玩的,上面两段代码没有进行任何错误的判定,所以使用时如果代码存在问题可能会遇到各种错误,两段代码也非常简单,想必看过之后就可以进行修改了~

     
    本文地址:http://www.cnblogs.com/ambition/archive/2012/02/17/my_hacker.html

  • 相关阅读:
    OpenNebula Restfull 接口请求示例
    [c++]堆和栈的区别
    [c++]程序的内存划分理解
    设计原则 依赖倒置
    设计原则 里氏替换原则
    设计原则:单一职责原则
    WPF 使用附加属性增加控件属性
    WPF 使用依赖属性自定义控件
    WPF EventAggregator(基于EventAggregator的事件发布及订阅)
    Struts2 Validate
  • 原文地址:https://www.cnblogs.com/ambition/p/my_hacker.html
Copyright © 2020-2023  润新知