pwnable之coin1

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-8
from socket import*
import random
import time
HOST='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=",ans
ans=client.recv(1024)#flag
print "ans=%s"%ans    
client.close()


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值