V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lesismal  ›  全部回复第 47 页 / 共 62 页
回复总数  1238
1 ... 43  44  45  46  47  48  49  50  51  52 ... 62  
2021-11-18 13:08:24 +08:00
回复了 TossPig 创建的主题 程序员 被客户告知 HTTP 的 PUT 请求不安全,甩锅给我们要求整改
本来交互协议主要两点:
一是路由,RPC 里叫方法,有的游戏为了节省流量和性能会用数值类型、叫命令号之类的,各个领域自定义协议的项目叫法都类似
二是参数。

之前楼写完上面的落了几句,补充上:
本来简单化一和二就搞定的事情,HTTP 协议非要搞成 Method + 路由 + 参数 三个层次,而且参数还可能有 header 里的 kv form ,还可能有 trailer 的 header 、body ,body 还可能 content-length 或者 trunked ,考虑到社区、历史、兼容因素,可以理解这样的做法。但是你说实际上这协议好不好,我是真没法说好。

饿殍遍野难民潮的时候,富人家施舍点粥米穷人都觉得香。
自己技术积累不够的阶段,社区、别人随便给个能用的轮子就觉得好用、牛逼。

美好的事物不能普遍占据主流——这才是主流的现实情况,劣币驱逐良币的历史故事和当下正在发生、未来也会不断发生的事情都多了去了,都是什么天时地利人和、顺应时代、场景者得天下罢了。

但美,仍然是美。
2021-11-18 12:46:07 +08:00
回复了 TossPig 创建的主题 程序员 被客户告知 HTTP 的 PUT 请求不安全,甩锅给我们要求整改
@debuggerx
> 达克效应:越无知的人越自信。

提出这句的时候也可以先送给自己,思考下自己是否听懂了别人在说什么。。。

> 总是有“高人”恨不得重新发明整个互联网。。。

第一,我没说过要重新发明,不是非要重复造轮子而是减少使用上的坑,少即是多
第二,我上一楼聊了点 http2.0 3.0 的,历史、社区兼容性占了很大因素,否则可能早就被优化了。考虑兼容,所以没法只能慢慢先从标准上推进、逐渐更迭,就像老龄社会一样只能等老旧项目自然死亡。
优化不意味着重新发明,而是软着陆,否则,如果不需要优化,你以为谷歌闲的蛋疼搞 quic 、社区闲的蛋疼接纳 quic 并且成为实际的 3.0 ?

拜托楼上某些位大神夸人或者讽刺之前先多了解下技术本身的点,比如 tcp http 协议的实现、历史时期的局限、有那些缺点、以后的优化方向,而不是只看眼下大家都这么用就跟着一块用,人云亦云不知所云也就算了,至少拿出点你们的观点、论据好吧,有论据 vs 无论据口嗨,我嫌累了
2021-11-18 12:37:05 +08:00
回复了 TossPig 创建的主题 程序员 被客户告知 HTTP 的 PUT 请求不安全,甩锅给我们要求整改
另外再跟你们说吧,我自己的 api 类项目里,连 GET 都不用的,统一 POST+结构化 body(json/pb/msgpack/...)

本来交互协议主要两点:
一是路由,RPC 里叫方法,有的游戏为了节省流量和性能会用数值类型、叫命令号之类的,各个领域自定义协议的项目叫法都类似
二是参数。

HTTP 协议本身算是互联网早期产品,设计者当年也都是摸着石头过河,但因为整个互联网不是自家项目,一旦协议定下来,要考虑全网兼容性,所以即使是缺点也不好及时匡正。包括不限于本帖里说的 METHOD 安全性,还有比如 keepalive 之前的短连接、请求不带 id 无法向多数 rpc 那样可以乱序响应所以即使支持 keepalive 和 server side pipeline 了仍然有线头阻塞的问题,甚至再往4层说,tcp 也渣,4层本身也存在线头阻塞的问题,所以各位可以看到,为啥 http2.0 还没普及,quic/http3.0 都出来了并且更被认可,而 quic/http3.0 是 udp 的,可以解决更多问题。
2021-11-18 12:28:42 +08:00
回复了 TossPig 创建的主题 程序员 被客户告知 HTTP 的 PUT 请求不安全,甩锅给我们要求整改
@rust 我得谢谢你夸我牛,哈哈哈,这一点我认,,
2021-11-18 12:12:10 +08:00
回复了 TossPig 创建的主题 程序员 被客户告知 HTTP 的 PUT 请求不安全,甩锅给我们要求整改
@dcsuibian #77
不要只当成 api 接口服务,还有可能同一套 nginx 有文件服务,系统还可能有其他的风险,能减少一个漏洞的点就减少一个,能减少一点工种上的耦合就减少一点耦合(最主要的是 PUT api 接口完全不是不可替代的)
2021-11-18 12:09:21 +08:00
回复了 TossPig 创建的主题 程序员 被客户告知 HTTP 的 PUT 请求不安全,甩锅给我们要求整改
@dcsuibian
那 PUT 是不是多了一点被人上传恶意文件的可能?
转的帖子里有:
“恶意攻击者就可以直接将病毒文件等传到 nginx 服务器上,所以 PUT 等方法对 nginx 来说是不安全的。”

至于黑客怎么玩,我不懂、不瞎吹。

如果说运维、安全人员、以及开发人员都对开放 PUT 的路由做好控制就没事,但就像我上面说的整个工程、团队协作各种耦合成本甚至审批流程,都提高了许多,尤其楼主这种好像还是不同公司之间的。
2021-11-18 11:56:37 +08:00
回复了 TossPig 创建的主题 程序员 被客户告知 HTTP 的 PUT 请求不安全,甩锅给我们要求整改
#74 如果不知道这个,那我能理解为啥好几位说没看懂了。
2021-11-18 11:54:07 +08:00
回复了 TossPig 创建的主题 程序员 被客户告知 HTTP 的 PUT 请求不安全,甩锅给我们要求整改
@dcsuibian
首先,你知不知道 PUT 和 DELETE 主要是可以用来上传和删除资源的 :joy:
2021-11-18 10:20:33 +08:00
回复了 TossPig 创建的主题 程序员 被客户告知 HTTP 的 PUT 请求不安全,甩锅给我们要求整改
@dcsuibian #51

> 这篇明显是有问题的,网上转过来也得自己思考下。
> 如果实实在在地打印过 http 请求中的内容,看过 http 的格式就知道 method 的最大区别就是第一行的格式。
>( http 是基于 tcp 的,只要你把 http 请求收到的 tcp 内容打出来看看就知道了)

我还算了解一点 tcp 和 http ,我这有一份手撸的 golang poller tcp 框架,支持了 http 异步解析,其中包括一份完整的 http parser:
github.com/lesismal/nbio/blob/master/nbhttp/parser.go

> 什么叫“从 Java 代码的角度考虑问题”?这跟什么语言都根本没关系,是 http 协议的内容。
> “在研发的代码里,终端(浏览器或客户端)过来的流量,最终通过 java 的注解,携带参数进入到了研发写了一个
> 方法里来了。”写这篇文章的人,明显就是直接上手 spring boot ,连基本的 http 协议都没了解过。

不管是不是 spring boot ,我都没出来你说这篇文章明显有问题是指什么问题。那篇文章作者的意思是从运维、安全部门部署的网关 /代理软件的层面不能允许 PUT/DELETE 这些方法,而从开发的层面不管什么 Method 都能拿到相关参数进行验证。
“这跟什么语言都根本没关系” —— 这句是对的。

> 至于什么 nginx 会遇到问题,那就去配啊。

nginx 的问题,,
我转的帖子的作者的意思是不同部门 /工种在整个工程实践的不同层上的安全考量角度,这跟用什么语言或者 java 用什么框架没关系,甚至 nginx 怎么配置都不适合这么实践——这一点我在上一楼(#43 )回复前面小哥的内容里面也提到过了,层主也可以看下

蹭住也可以多思考下,然后再看看我是不是转帖时候没思考 :joy:
2021-11-18 07:23:01 +08:00
回复了 TossPig 创建的主题 程序员 被客户告知 HTTP 的 PUT 请求不安全,甩锅给我们要求整改
@ryd994

> 用于 Web 服务的 Nginx 为什么要带 dav 模块编译?各大发行版的默认 Nginx-minimal 就是没有 dav 模块的。你为什么编译的时候不可以关掉

人家原文里说:
```2 、为什么说 PUT 、DELETE 是不安全的方法?
对于 nginx ,可以使用 HttpDavModule 编译 nginx (./configure --with-http_dav_module ),开启 PUT 、DELETE 等方法。开启后,恶意攻击者就可以直接将病毒文件等传到 nginx 服务器上,所以 PUT 等方法对 nginx 来说是不安全的。
```

这意思没说默认就有 dav 模块吧?也没说默认就开启吧?人家这意思说的就是默认不开启、如果需要开启单独编译吧?所以你要不要再自习看看 :joy:


> 其次,Nginx 的 dav 模块是需要 dav_methods 指令开启的。还可以根据不同路径使用不同的设置

你有没有想过今天给你开一个特殊的明天给他开一个特殊的,安全部门还得维护各种,开发与运维、安全人员耦合,而且毕竟留了口子,哪天不小心、或者包括人员离职交接、新功能上线导致纰漏留了漏洞等情况?而对于开发而言,统一协议规范、提高这点安全标准并不费多大事,为什么要为了开发自己的便利去与更多部门产生工程上的耦合?代码讲究高内聚低耦合,但代码是服务于整个工程的,工程思维要考虑整体,包括架构、运维、安全相关的部门协作等各种,只考虑自己方便不是一个好的努力方向

而且,我上楼转那个帖是为了说明 PUT 不安全相关的问题,所以,nginx 编译方案并不适合作为安全问题甩锅的理由


> 自己不会配置 Nginx 还要怪 restful 不行?

抛开 nginx 不谈,restful 就好用吗?
1. 真实项目里有多少人在用真正的 restful (只是用了各种 method 就以为是 restful 这种不算)?
2. 有多少人真正理解了 restful ?不怕各位笑话,我就没太懂,因为搞得太绕太复杂,要理解它所谓的精妙设计就要不少心智成本,就像有人讨论说的,它跟 OOP 一样存在过度抽象的问题,需要前期消耗很多顶层设计、预先设计的成本,我只是人云亦云、具体我是不了解了,因为好的东西讲究大道至简少即是多,这种搞一堆套路定义的东西、把本来可以简单的问题复杂化,看半小时还没入门、让人云里雾里的东西,我默认它是垃圾。
3. 虽然我不真的懂 restful ,但是可以简单对比下 restful 和 GET/POST+结构化 body 的方式,最简单的思考,restful 不仅多种 method 要仔细设计,仍然也需要 body 参数的结构化设计,而 GET/POST+结构化 body ,省去了 method 设计这块的心智成本,哪个更简单省力?另外,抛开 web 领域,其他服务器领域,命令号 /路由+结构化 body 到处再用,IM/游戏 /分布式系统内部 RPC 交互,也就 HTTP 这垃圾协议早期设计者内心戏太多搞得这么复杂,号称的文本协议可读性好都是扯淡,即使二进制协议,浏览器或者其他工具转换一道可视化出来也不是啥问题,但对于整个互联网流量、算力会带来巨大的节约,相应的也是巨大的性能提升。早期的用户量小,这点协议复杂带来的成本不高,现在都互联网爆发的时代了、大数据的时代了,HTTP 协议的复杂性带来的能源消耗都是不小的开销,只是历史包袱太重没法随便切换成更高效的协议,我目测相比于更高效的二进制协议,它浪费的能源甚至不比挖矿少。

所以,是大家 “怪” restful 不行还是它真的不行?
2021-11-18 00:37:49 +08:00
回复了 lesismal 创建的主题 Go 编程语言 最近犯闲,想再写点啥项目,有推荐的吗?
@XTTX mattermost 很 slack ,我也先收藏个,谢谢!
2021-11-18 00:33:14 +08:00
回复了 TossPig 创建的主题 程序员 被客户告知 HTTP 的 PUT 请求不安全,甩锅给我们要求整改
@SimonOne
随便就搜到个:blog.csdn.net/CHEndorid/article/details/111277629
而且和楼主公司的情况挺像的,不会就是同一个公司吧?

直接贴过来:

```text
一、背景
最近研发让我开一下服务器的 put 、delete 方法,被我以不安全的 http 方法给拒绝了。

研发表示我很无理,put 怎么就是不安全的了,在他看来,put 和 post 只是语义上的不同。如果 put 是不安全的方法,那么 post 也是不安全的方法了。

网上的说法也是分为两派,一派说这些都是不安全的方法,要关掉;另一派说它们只是语义上的区别,不存在安不安全。

二、一探究竟
经过我和研发各自编写测试用例来论证后,我明白了为什么会有这样的分歧:我是从 nginx 作为 web 服务器的角度来看问题的,研发是从 java 代码上来看问题的。

1 、为什么说 POST 和 PUT 只是语义上的区别?
在研发的代码里,终端(浏览器或客户端)过来的流量,最终通过 java 的注解,携带参数进入到了研发写了一个方法里来了。比如研发对某个自定义方法使用 PUT 的注解,那么终端通过 PUT 方法传递的参数就会进入到这个自定义方法中。有点编程经验的话,就会知道,到了你写的方法里,这些参数就随便你玩了。

对于 PUT 、POST ,研发都可以通过添加不同注解的方式,得到传递的参数,然后进行操作。所以研发会认为他们只是语义上的区别。

2 、为什么说 PUT 、DELETE 是不安全的方法?
对于 nginx ,可以使用 HttpDavModule 编译 nginx (./configure --with-http_dav_module ),开启 PUT 、DELETE 等方法。开启后,恶意攻击者就可以直接将病毒文件等传到 nginx 服务器上,所以 PUT 等方法对 nginx 来说是不安全的。

3 、上面两个问题是否矛盾?
并不矛盾。

假如研发人员打包一个 jar 包,这时客户端直接访问这个 jar 包起的服务,那么 put 传递过来的所有参数,是可以由研发人员编写的代码控制的。只要控制得没有猫病,那么就是安全的。假如开发的是一个 tomcat 容器部署的工程,参数也是一样可以由研发的代码控制的。

同时,用 nginx 也可以反向代理 put 方法(不用 HttpDavModule ),所以只要后端服务对 put 服务做好控制,nginx 不需要做任何更改,也就实现了对 put 方法的支持。

但 nginx 不能单独开启 put 等,因为研发的代码不能对 nginx 做控制。

三、结论
后端服务可开启 put 方法,只需要后端服务对 put 传递的参数做好控制,并实现 put 方法即可。

nginx 不可开启 put 方法,这是一种危险的方法。
```


另外:竟然真的有人认为 REST 挺好,是有多傻。
2021-11-17 19:04:40 +08:00
回复了 lesismal 创建的主题 Go 编程语言 最近犯闲,想再写点啥项目,有推荐的吗?
@XTTX #9

不同体量的 IM 项目架构差别很大,比如几种:
1. 上古时期的 web 实时聊天室,网站总在线量不大,随便起个名字进房间,主要是文字或者固定表情,并且单房间在线数一般不打,实现逻辑简单,需要踩坑性能的也就是广播时候可能会涉及广播风暴需要做点批次合并发送的优化
2. 目标在线量不大但是有更多功能的 IM ,比如企业内办公用的,除了文字和固定表情,常见的传文件、发自定义图功能也有,因为在线量不大,数据、文件存储层不涉及太多,也不需要太复杂的分层、路由设计,单体架构随便都能搞定
3. 海量在线,比如 QQ 这种,文字表情文件图片语音等各种功能,除了代码架构的分层设计、路由,还需 CDN 各种运维相关的工程部署,需要数据库、缓存、小文件存储各方面的横向扩容机制,需要多机房等各种

每种定位不一样,人力、资金成本和架构、开发周期也差别大,只能按实际的搞,但单纯从需要的技能点来讲,长连接协议交互这块都不算难,更多难点是工程、尺度上的设计。

开源的有一些也可以作为参考:
B 站毛大的:
github.com/Terry-Mao/goim
前微信大专家:
github.com/OpenIMSDK/Open-IM-Server

我只是看到过社区、公众号之类的推这些开源项目相关的信息收藏起来了,没有深入研究,所以没有了解他们具体的架构、能够支持的用户量级和业务场景,通常够用了,自家可以定制化。

IM 支持的消息,需要分类对待:
1. 文字 /表情,表情也是可以 id 指代的所以也相当于文字,nosql 系的数据库有好些,或者 tidb 或者自己设计可以方便横向扩容的存储层都可以
2. 图片音视频或者其他类型的各种文件,需要文件存储的基础设施,开源的也比较多,开源直接拿来用,这其中可能还涉及小文件存储,应该跟大文件区分开,文件元信息也是可以放到数据库里,头条的小文件存储元信息好像是放到 tidb 里的

如果目标在线量不大,那就简单得多了

如果有兴趣积累 IM 的技术,你可以尝试自己动手从零开始搞一个,我那个 arpc 能够作为 IM 的长连接协议交互基础设施,最简单的就房间文字聊天转发,很简单,这里有个例子:
https://github.com/lesismal/arpc/tree/master/examples/webchat
2021-11-17 15:51:12 +08:00
回复了 lesismal 创建的主题 Go 编程语言 最近犯闲,想再写点啥项目,有推荐的吗?
@XTTX #4
> 一个 ip 支持同时 65k 个 ws

这个说法不准确。一个 ip+一个 listen port ,跟另一个 ip 最多可以 64k 个连接,这还要受到系统参数限制比如 net.ipv4.ip_local_port_range 。

四元组的概念是基于 3 层的 ip 协议,四元组包括:
A IP && A PORT - B IP && B PORT

ip 协议 port 字段是两字节,而 tcp server 通常是 listen 固定的 port ,相当于 A IP && A PORT 固定,对于另一个 IP ,相当于 B IP 也固定,所以只剩下 B PORT 范围可变,所以就受 port 字段类型的限制,2 字节,64k ,再加上内核参数的限制。

但是如果 tcp server 监听 n 个 port ,B IP 就可以跟 A IP 建立更多连接数:n * min(64k, 内核参数限制)。

所以很多人单机测百万连接数要搭建 docker 或者虚拟网络,我为了省事,直接开多个端口,免去搭建的麻烦了:
github.com/lesismal/nbio-examples/blob/master/websocket_1m/server/server.go#L68
2021-11-17 15:37:52 +08:00
回复了 lesismal 创建的主题 Go 编程语言 最近犯闲,想再写点啥项目,有推荐的吗?
@kksco
网络协议涉及的知识稍微多一些,实现一个只处理收发的网络库本身涉及的东西其实不算多,熟悉和理解阻塞非阻塞同步异步这些,熟悉 epoll 基本就可以了,甚至从零开始熟悉,边搜资料边实现个简单的 epoll server ,把 et|lt 都试试,跑跑压测,几天就玩明白了,再不济,随便搜几个开源的 epoll server 代码读一读就好了,网络库的读写部分代码量不需要很多,很容易就搞懂了。

然后是需要一些周边的东西了,比如定时器、io 线程池、逻辑线程池,然后再搭配其他基础设施,传统 c/cpp/java netty 都是异步为主的这里是线程池,go 是协程池,有一定差别,因为有协程的亲和性也好、gc 也好、代码指令速度也好,相比 c/cpp 肯定要差一些,所以通常不像主流的 c/cpp 网络库那样逻辑单线程,所以就会有多逻辑并发流相关的设计。再然后就是 http/websocket 这种 7 层协议的支持。

还有内存相关的优化,c/cpp 可以用 tcmalloc/jemalloc 之类的内存池,go 自带 gc 但是在异步网络库场景可能会造成比标准库同步方案更浪费内存的情况,所以可能也需要结合业务自行设计 pool 来优化内存使用。
另外 go 缺少异步的 tls 库,我 copy 1.6 的标准库 tls 魔改支持了异步,并且把 tcp 层 Conn 读写与 tls 、http 、websocket 都打通了共用内存池,尽量减少了开销(某些极端场景也会消耗较大内存,但通常按照业务实际情况可控)。
过去的几个月里,tls+内存池优化消耗了我最多的时间,因为 tls 本身的复杂+异步流解析+内存的精确分配释放确实有点烧体力。

关注过一些国内大厂人的开源视频流服务器,但简单 review 了下代码,有的地方 map 的并发读写都没处理好,高并发时容易出现 panic 、整个进程挂掉,所以前阵子其实还想搞一下视频编解码多协议的支持来着,但估计了下,实在是消耗体力,还是先算了。

需要注意的一点是,nbio 这种异步网络库,连接数少的时候并不比标准库一个连接一个甚至两三个协程的方案有响应速度的优势,甚至是劣势。标准库占用更多内存,但响应性可能更好。只有在连接数较大、协程数量带来的内存、gc 、调度等开销达到临界点时,nbio 才会有明显优势、服务更稳定。因为异步解析以及消息处理要丢给逻辑协程发生调度、不如标准库同协程内那么亲和性友好。nbio 的能力是可控的协程数量,比如 1000k 连接数我可以控制在 100 、1000 或者 10000 个逻辑协程处理,不会因为连接数暴涨而协程数量爆炸导致明显的 STW 甚至 OOM 。

之前有打算整理一份详细的 nbio 的设计与实现,但是列了一些提纲后发现展开了说够写一本书了,想写好点的话弄本书,参考之前一些首次出书的作者的心路历程,这个工作量业余时间搞至少需要一两年,所以暂时放弃了,以后如果有体力再考虑。并且网络库相关的,市面上已经有不少书了,传统好书看 Stevens 的 tcp/ip 详解卷一,卷二和卷三就不用看了,纸上源码确实难啃而且有些老旧了,UNP 两卷,网络那卷应该算必读吧,进程间通信那卷也可以看看,至少对 uni*发展史和基础的 IPC 机制都能有些了解,而且 Stevens 的书都写的很好,读他的书就像在跟他交流一样,APUE 也是这样子的。
其他的一些书,linux 服务器、高性能相关的,陈硕老师傅有个 cpp 的 muduo 框架和书,我没怎么研究过,但扫了一眼书的目录还挺全面的,可以读读看
2021-11-17 15:02:26 +08:00
回复了 lesismal 创建的主题 Go 编程语言 最近犯闲,想再写点啥项目,有推荐的吗?
@XTTX #1 每个人备份需求不一样,这个得自己搞,查找的话本身挺简单的,小工具按条件遍历下目录就行了
2021-11-11 10:37:33 +08:00
回复了 grimpil 创建的主题 Python 从 10 亿位数字里查找指定的数字,怎样才能快一些?
@c0xt30a 不用那么麻烦的 hash ,要查询的数字 n 具有上下限并且值范围不是特别巨大,用要查询的数字 n 作为数组下标就行了,数组的值就是 n 对应的在 pi 中的 index
@arthurire KMP 是 O(m+n) 的,字符串本身达到 10 亿量级,O(m+n) = 10y+8 也是没法接受的

#34 楼已经实现,建好数组就相当于位图了,时间复杂度 O(1)
2021-11-11 00:22:06 +08:00
回复了 grimpil 创建的主题 Python 从 10 亿位数字里查找指定的数字,怎样才能快一些?
算了,忍不住还是调试了下,完整版的:
https://gist.github.com/lesismal/c4528eacc35db33f754ac2f8eb9e7634
2021-11-10 23:53:39 +08:00
回复了 grimpil 创建的主题 Python 从 10 亿位数字里查找指定的数字,怎样才能快一些?
#32 文件尾、打开写文件的好像都有问题,平时不写 py ,实在不熟悉,v 站发代码也确实难受,对齐好像都没了
2021-11-10 23:46:44 +08:00
回复了 grimpil 创建的主题 Python 从 10 亿位数字里查找指定的数字,怎样才能快一些?
用数据库存上也是慢,内存里缓存起来性能最好了,下面代码大概意思是 converter 先统计好索引到数组,然后把数组写入到文件,finder 读入文件初始化数组,然后再查找。没仔细调试,因为太烧机器了,有兴趣的同学可以完善下:

1. converter.py
```python
# -*- coding:utf-8 -*-
#!/usr/bin/python3

import datetime

class PIConverter:
def __init__(self, minNum=100000, maxNum=99999999):
self.minNum = minNum
self.maxNum = maxNum
self.positions = [0]*(self.maxNum+1-self.minNum)

def convert(self, srcFile, dstFile):
fsrc = open(srcFile,'r')
fsrc.read(2)
try:
lastStr = ""
readSize = 1024*8
currPos = 0
readed = 0

starttime = datetime.datetime.now()

offset = len(str(self.minNum)) - 1
while True:
s = fsrc.read(readSize)
s = lastStr + s # 这里可以再优化下
currPos -= len(lastStr)
for i in range(len(s)-8):
strLen = len(str(self.minNum))
while strLen <= len(str(self.maxNum)):
subs = s[i:i+strLen]
strLen += 1
num = int(subs)
index = num - self.minNum
if self.positions[index] == 0:
self.positions[index] = currPos + i

if len(s) == 0:
break

lastStr = s[len(s)-5:]
currPos += readSize
readed += readSize
if readed % (1024*1024*8) == 0:
print("total read: {}, time used: {}s".format(readed, (datetime.datetime.now() - starttime).seconds))

print("total read: {}, time used: {}s".format(readed, (datetime.datetime.now() - starttime).seconds))
print("done")

try:
fdst = open(dstFile,'rw+')
for index in range(self.positions):
fdst.write(str(index)+"\n")
finally:
fdst.close()
finally:
fsrc.close()

def find(self, n):
if n < self.minNum or n > 99999999:
return -1
return self.positions[n - self.minNum]

piConverter = PIConverter()

# 把已经统计出来的生成更小的文件
piConverter.convert("./pi-billion.txt", "./pi-position.txt")

# converter 初始化太慢了,所以最好还是先 piConverter.convert 把已经统计出来的生成更小的文件,finder.py 用该文件初始化和做查找
# print("141592:", piConverter.find(141592))
# print("415926:", piConverter.find(415926))
```

2. finder.py
```python
# -*- coding:utf-8 -*-
#!/usr/bin/python3

class PIFinder:
def __init__(self, fname, minNum=100000, maxNum=99999999):
self.minNum = minNum
self.maxNum = maxNum
self.positions = [0]*(self.maxNum+1-self.minNum)
f = open(fname,'r')
try:
i = 0
for line in f:
num = int(line)
self.positions[i] = num
finally:
f.close()

def find(self, n):
if n < self.minNum or n > 99999999:
return -1
return self.positions[n - self.minNum]

piFinder = PIFinder("./pi-position.txt")
print("141592:", piFinder.find(141592))
print("415926:", piFinder.find(415926))
```
1 ... 43  44  45  46  47  48  49  50  51  52 ... 62  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1045 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 115ms · UTC 20:04 · PVG 04:04 · LAX 12:04 · JFK 15:04
Developed with CodeLauncher
♥ Do have faith in what you're doing.