pwnable之coin1

来源:互联网 发布:佳博网络打印机设置 编辑:程序博客网 时间:2024/04/28 09:22

coin1

题目的意思是在一堆硬币中有一枚假硬币,假硬币的重量是9,而正常的是10。现在有N枚硬币,你可以询问C次。每次询问返回的是你询问的硬币的质量之和。询问C次之后,就要告诉它假的硬币的编号。

比如

[server] :N=4 C=2
[client]   :0 1
[server] :20
[client]   :3
[server] :10
[client]   :2
[server] :Correct!

重复100次,你就能拿到flag。

一道简单的二分题,但要求30秒内完成100个用例。如果在本地运行coin1.py,我的网速解决10个用例就超时了。题目有提示,你可以在它的服务器里运行。任选原来在pwnable.kr做过的题。比如ssh shellshock@pwnable.kr -p2222 (pw:guest)
然后 cd /tmp
 touch coin1.py
 vi coin1.py
编辑你的文件
# coding: utf-8from socket import*import randomimport timeHOST='0.0.0.0'PORT=9007#建立socket对象client=socket(AF_INET,SOCK_STREAM)#AF_INET表示将使用标准的ipv4地址或主机名#SOCK_STREAM说明这是一个TCP客户端    client.connect((HOST,PORT))#连接data = client.recv(1024)time.sleep(4)for i in range(100):    data = client.recv(1024)#接收数据    int_cnt=data.find('N=')+2 #int_cnt用于找到N,C    N=0    C=0    while True:             N+=int(data[int_cnt])        int_cnt+=1        if data[int_cnt]==' ':            break        N*=10    int_cnt=data.find('C=')+2    while True:             C+=int(data[int_cnt])        int_cnt+=1        if data[int_cnt]<'0' :            break        if data[int_cnt]>'9' :            break        C*=10    print 'get N=%d'%N,'get C=%d'%C#打印N,C    left=0    right=N-1    mid=(left+right)/2#二分    for i in xrange(C):#C次询问         str_ask=[str(n) for n in xrange(left,mid+1)]        str_ask=" ".join(str_ask)#构造要询问的硬币        client.send(str_ask+"\n")#发送数据        str_weight=client.recv(1024)#接收数据        str_weight.split("\n")        int_weight=int(str_weight)        print "int_weight = ",int_weight,"l=%d mid=%d r=%d"%(left,mid,right)        if int_weight!=((mid-left+1)*10):            right=mid            mid=(right+left)/2        else:            left=mid+1            mid=(left+right)/2    client.send(str(mid)+"\n")    ans=client.recv(1024)    print "ans=",ansans=client.recv(1024)#flagprint "ans=%s"%ans    client.close()


0 0