Shell's Home

关于民用航空上禁止使用电子设备的分析

Jan 5, 2013 - 1 minute read - Comments

适用对象 本文论述的电子设备,包括以下几类: 不显式使用无线信号通讯,仅在工作时被动发出噪声的电子设备 使用2.4GHz频段和5GHz频段的wifi类和蓝牙类短距离通信设备 使用800MHz和1800MHz频段的长距离通信设备 本文论述的设备,不包括非法无绳电话等设备。尤其是不要把非法无绳电话当作普通的无绳电话,那玩意使用伞状天线,覆盖范围最高可以达30公里,根本就是私人设的无线电基台。使用频率又和飞机一致,飞机从上面过,通信马上就被干扰了。 飞机无线系统的工作状态 飞机自身也是大型机电设备,也会显式的使用无线进行通讯和导航,或者做系统控制(但是下面某个事故案例表明,使用无线作为系统控制是不可能的,飞行中的系统控制必然使用有线)。 飞机主要会使用的无线用途包括两大类,通讯和导航。 根据我在这里找到的资料,飞机常规的通讯频率为118.000~135.975MHZ。同时,中国民用航空总局无线电管理委员会办公室的某份文件佐证了这一说法。因此,常规飞机的主要通讯频率为121.5MHz、243MHz两大频率段。 而导航则比较复杂。如果是GPS导航,一般的L1频率段是1575.42MHz,L2的频率为1228MHz。而近距离的多普勒雷达和机载天气雷达工作范围都在1-10cm波长下(这个受限于天气因素),频率大约是3GHz-30GHz。CAAC的文件规定,中国范围内的多普勒天气雷达的X波段为9300-9700MHz,C波段为5300-5700MHz,S波段为2700-2900MHz。 飞机对无线信号的耐受性 首先,如果飞机的通讯频率被大功率干扰,可能引发地面引导失效,造成严重后果。因此,飞机的通讯频率(121.5MHz、243MHz),GPS频率,都不允许同频率信号。 另外,如果干扰设备功率足够大,频率又处于比较高的位置。那么可能引发混叠现象,干扰低频设备的工作(不知道我有没有理解错误)。因此,在飞机上应当禁用任何高频率的大功率设备。 航飞安全禁令的来由 目前在各种航班上实行的安全禁令,是由FCC在1991年所规定的,并得到FAA的支持。然而,这一禁令最初针对的是上个世代的水壶型大哥大设备等,而且当时的飞行设备并没有经过专门考量,对民用的广泛分布的无线信号做出抵抗。由于当时基台密度比现在远低,因此这些设备的发射功率比目前的手机要大上很多,1-2W属于常态功率。因此FCC顾虑到,在飞机上使用手机可能对飞机的通信造成安全,从而影响顾客人身安全。因此,尽管没有明显而直接的证据,但是FCC仍旧颁布禁令,禁止在飞机上使用手机。 一点直接的佐证即是,飞机上并没有配置无线信号定位系统。如果手机真的对飞行安全形成了直接的威胁,那么飞机上必然会配置手持式无线信号定位装置,借助三角定位法找出未关闭的手机。从无线技术原理上说,这是做的到的。这种做法可以有效补强空乘人员寻找手机的漏洞。正是由于手机的威胁仅仅是间接证据推测,因此飞机上始终未曾配备这些设备。 这里体现的是一种谨慎原则,当某个新鲜事务可能对人类产生威胁时,如果没有明确证据表明“没有威胁”,则默认断言“存在威胁”。在面对未知的,新生的事务中,谨慎原则不止一次的拯救过人类。当然,与此相对的,也不止一次的由于过度谨慎而坑过爹。然而在综合双方带来的影响后,人类仍然坚持了谨慎原则。这本质上是对有利可图的商家,国家,或者其他掌握力量的个人或组织的警惕。 但是,在经过长时间的接触后,谨慎原则是否适用,可能会需要重新评估。如果坚守谨慎原则,第一件应当被禁止的事情不是飞机上的手机,而是汽车。全球每年死于车祸的人高达几十万,只要禁用掉汽车就没这个问题了。可是谁也不曾提出过禁止汽车上路(中国某些部门的新交通法规是个例外)。正是因为人们感受到,汽车对人类带来的好处远远大于造成的问题。 同样,电子设备是否可以用于飞机上,这个问题也需要随着电子工程的发展和电子产品深入人们的生活而重新评估。在这里可以毫不客气的说,由于电子产品已经深入了人们的日常生活,成为生活的一部分。如果无原则的坚持禁令,就是反人类。在这种情况下,需要考量的不是坚持还是不坚持禁令的问题,而是需要重新审视和设计,制造飞行器,使其可以满足人类随时进行通讯的基本需求。 对于不显式发出无线信号的设备 这类设备没什么好禁用的。不过这句话要说的比较严密,应当是加上限制,在设备本身辐射不大的情况下。显然,微波炉本身也不显式的发出无线信号,可是那玩意的电磁泄漏明显不适合在飞机上使用。 但是话说回来,有几个SB会把微波炉带上飞机的! 而且很大程度上,这类设备并不能真的“禁用”,因为不少人类生活严重依赖于电子设备,例如人工心脏起搏器,或者是电动轮椅,助听器。固然,航飞部门可以发布警告,提醒使用以上设备的人乘坐飞机的风险。但是不能在没有明显理由的情况下拒绝乘客,因为他们使用了助听器。 对于使用2.4G和5G频段的短距离通信设备 2.4G是国际规定的无线保留频段,使用这个频段不需要特殊的申请或者执照。因此,如果在2.4G引发了干扰,干扰源又是按照标准(<100mW)的,那么被干扰者只有自己摸摸鼻子认倒霉。例如深圳某地铁使用2.4G频段作为闭塞用,结果被干扰导致列车老停车,这就明显是设计者考虑不周。 频段上没问题了,我们再说说功率。常规的wifi设备功率都在50mW以下,而且一般功率只小不大。因为发射功率的增加是以增加耗电量为代价的,便携设备哪里来那么多电给你消耗。真正功率比较大的,常见的是用于蹭别人家网用的特制无线网卡,俗称“卡皇”。其功率从200mW到数瓦不等。部分设备甚至可以截听公里级别的wifi信号,功率超过手机。这部分违规设备应当严禁携带上飞机。 对于100mW以下的合法设备,不应当处于飞机无线管制的范围内。预计在可见的将来,针对近距离通讯设备的禁令就可能会解除。即飞机上的广播中,应当会去掉“请关闭手机的无线功能”等。作为作证,可以参考这条新闻,云南三架飞机将提供WIFI服务。如果不取消禁令,又自行提供wifi信号,岂不是自打嘴巴?当然,安全起见,在飞机的起飞和降落期间还是应当关闭wifi热点。 使用800M和1800M频段的通信设备 这个又要分的比较严密了。这类的设备主要分为两种,GSM和CMDA2000。严格来说,GSM的信道才是900MHz,1800MHz和1900MHz,CDMA2000的信道是上行1920~1980MHz,下行2110~2170MHz。功率都是1-2W左右。 然而GSM方式造成的干扰比CDMA方式严重的多。因为CDMA基于码分多址,而GSM基于时分复用。由于是时分复用,因此设备只能在许可时隙内发射信号,信号呈脉冲型。脉冲型的信号调制就坑爹了,因为脉冲信号的开始和结束时会对其他频率造成影响。关于这点我不知道怎么向没有高等数学基础的读者表达,大致理论是一个方波可以被变换为一系列正弦波的加成。 由于这一特性,因此FCC才会顾虑GSM对飞机通讯系统的干扰。 因此,我觉得航飞系统未来可能考虑解除CDMA的禁令,或者更进一步,在机内部署低功率CDMA基站。因为CDMA对其他信道的干扰小,而基站在附近产生的干扰更加小。在机内建立基站有几个好处。 降低手机辐射。非常悖论的,当手机无法接收信号的时候,其功率最大。因此一旦在飞机内建立基站,手机的发射功率就会受到控制。 将CDMA转为飞机可以容耐的地-空通讯,提供飞机上拨打电话的功能。当然,这个特性可以作为飞机服务加以运营。 至于GSM,貌似在可见的未来并不会纳入考量。 飞行模式 鉴于飞机上不允许使用手机,而智能机又迅速普及,很多厂家推出了“飞行模式”功能。飞行模式的原理,在于手机可以通过软件关闭GSM通讯模块和wifi/蓝牙通讯模块,从而使得设备从普通通讯设备变成不显式发出无线信号的设备。从原理上说,这确实是可行的。 然而很多航空并不买账,其机上禁令仍然包括“飞行模式”。 我不知道这基于一个什么样的理由,至少不是纯技术层面的理由。因为从技术上说,飞行模式的手机产生的干扰远比电脑低。根据某些报道,这可能是由于山寨手机厂出品的手机,并没有真的实现“飞行模式”,而是仍旧发射无线电,只是软件上禁止了接入和拨出。 不得不说,很多事情就坏在这些SB身上了。 关于飞机上的手机信号 即使在飞机上完全没有手机的情况下,也无法隔绝手机信号对飞机的影响。大功率基站在没有干扰的情况下,覆盖范围可达10公里,而飞机一般的飞行高度都在3公里-10公里之间。因此如果飞机围绕着一部基站盘旋,从飞机上完全可以进行手机通话。当然,如果飞机沿着径向行驶,那么会引起很强的多普勒效应(比火车速度快很多),从而造成拨打困难。所以说,运气好的情况下在空中开机居然还有信号,就是这个道理。作为例子,在911事件中,有部分乘客可以通过手机向外部传递信息。 鉴于此,也许在10年后,由于飞机的更新换代,老机型的淘汰。上飞机就不需要关闭手机了。 关于1991年某飞机因为手机反推装置打开的说明 网络上多半是流传1991年某英国航空,我找了一下空难列表,1991年反推事故的貌似只有劳达航空004号班机号空难(也称奥地利航空,不过好像被收购过,所以具体不明),具体可以看wikipedia页面。 根据下面给出的劳达航空004号班机的事故调查报告,我通篇找不到手机(mobile),或者干扰(intrusion)之类的字眼。事故原因分析貌似是说,因此由于某些照明电路的电路故障,导致反推装置启动。在系统改进中,也没有要求飞机上关闭手机的建议,只是建议飞机上的电子设备增加屏蔽装置,屏蔽电磁干扰。注意,这里屏蔽的目标不是无线通讯干扰,而是电路故障造成的电火花(hot short)。 同时,飞机也会频繁穿越积雨云之类的电磁异常区域。由于飞机上的控制系统异常重要,而飞机本身的电磁环境不稳定,因此使用无线控制飞机是不可行的。 关于在医院使用手机的问题 医院使用手机,电脑是一个需要慎重考虑的问题,因为确实有很多医疗设备使用了2.4G频段。甚至由于人体器官尺寸等原因,有很多医疗设备并不能自己选择工作频率。例如在深圳的地铁干扰问题上,医院的B超亦是干扰源之一,见这里。可以想见,如果将卡皇带到医院去使用,也可能对B超设备产生干扰。 但是,对上述新闻,我抱持怀疑态度。借助声波工作的B超为什么会发射如此强烈的电磁信号,而且信号频率居然高达2.4G。这本身就是件很奇怪的事。由于报道并没有列出关联信息,因此无从查起,姑且信之。

支付宝体系的问题

Dec 31, 2012 - 1 minute read - Comments

今天和几位朋友讨论了一下支付宝的问题,又查了一下case,发现支付宝的问题不仅是那么简单而已。先不吐槽支付宝的问题了,赶快出验证和方案。 在被人恶意补卡的情况下是否安全 关于恶意补卡,这里有个例子。简单来说,就是知道你的身份证和手机号,去异地营业厅用假身份证补手机卡。然后用手机卡获得支付宝系统,再套现。 贝壳分析了自己的系统,如果恶意补卡的话,对于200以上的消费转账,会要求输入宝令。宝令是绑定在手机而非卡上的,所以攻击者会无法消费。而要取消宝令就必须输入宝令,通过手机卡无法取消。因此攻击者即使补贝壳的卡,也无法进行200以上的消费。 但是如果你用的是U盾,那问题就没那么简单。在支付宝的设计中,手机是可以解除U盾绑定的。所以U盾不能对抗恶意补卡。 结论:如果仅仅是200而已,我可以认为这个系统是安全的。 在手机丢失的情况下是否安全 如果手机丢失,问题就更加严重。支付宝密码,支付密码均会被找回,宝令本身就在手机里,因此支付宝的支付系统全面沦陷。支付宝内资金肯定不保。问题是卡上资金。 贝壳绑定了两张卡,浦发和招商,先从快捷支付检查起。检查浦发的卡发现,对支付宝默认开了20000的签约支付额度,当场汗就下来。对于快捷支付来说,这太高了。速度改成300。对于超过300的,依然可以通过网银验证来支付,比较安全。 招行的快捷支付我从头到脚就没看到签约这回事,貌似必须进行网银支付。那就需要我的卡号有效期密码什么的。我觉得这个不大可能出问题。 再检查浦发的普通支付,这需要登录浦发的网上银行。浦发网银是通过手机加密码验证的,基本可以保证转账汇款的安全。 结论:目前调整的结果,一次损失300左右。 网银的一点隐忧 目前网银的密码都太弱了。浦发只有6位数字,招行也只有8位数字字母。难道就不能设定强一些的密码么? 浦发可能是要和卡本身的密码兼容,将手机作为补强。可是手机也会掉啊。一旦手机掉了,整个安全性就由6位数字密码保护。这和掉银行卡一样严重。 建议 移动和联通关闭身份证显示,尤其是最后四位! 无论哪种级别,使用支付宝一定要打开宝令。目前只有宝令可以有效对抗补卡攻击。 在智能机上又绑定网银的,就不要乱装软件,更不要root/越狱。 中国移动的补卡修改流程。如果当前卡处于激活中,先持续警告旧卡24小时后再激活新卡。 移动至少应当允许客户自行选择“这个手机号码极端重要,不得实行异地补卡,不得显示个人信息,复机/补卡间隔需要在24小时以上”的增强选项。 理论上说,移动应当可以推进二代身份证验证能力。使得补卡业务实行时,必须凭借二代身份证验证身份后进行。杜绝假身份证。 支付宝的密码找回功能降速。从开始找回,发短信和邮件通知,到完成找回密码至少要一小时,最好要24小时才能找回密码。或者允许可以设定“我自愿将找回密码时限改为24小时”以增强安全性。

移动的一点漏洞

Dec 30, 2012 - 1 minute read - Comments

今天支付宝的那个问题,支付宝的人和我说。 猜到就是手机保存账户名可以找回密码的问题。。对于快捷用户明年会要求手机+证件找回密码,减低200以上的资损风险。所以现在我客户端使用后都删除用户名纪录,为了安全。那个token的想法挺好的! 我就考虑,是否可以通过手机获得身份证呢? 首先,利用手里的手机,得到自己的手机号。然后查询所在地,在对应的移动网站上(例如上海移动)找回密码,然后登录移动网站。进入个人信息管理,需要手机验证码。输入验证码,可以看到部分身份证。包括头4位和尾4位。普通身份证是18位的,分组方式6+8+4。隐藏掉的10位中有8位是生日,一般手机里都能找到,并不困难。 因此,实际需要得到的就是2位。而这两位又不是任意的,和个人出生地有关。具体到我的身份证上,有了前四位后,两位只有17种可能。我看了其他一些人的情况,运气差的情况下,这两位只有一两种可能,例如1405,山西省晋城市,只有00/01/02。全试一遍就可以了。 更新:同事反应,联通的网站更二,直接就显示了完整身份证。。。 更新2:同样漏洞,在招商银行的手机应用上也爆了出来。。。

支付宝的一项设计问题

Dec 30, 2012 - 1 minute read - Comments

话说最近,贝壳成批更新了一些密码。在更新到网络支付系统的时候,心血来潮做了个分析。感觉网银系统很不安全。尤其是支付宝的手机客户端。我们下面以一个实际例子说明一下支付宝系统(其实远不止支付宝)的问题。 情况说明 贝壳的支付宝系统做了手机和淘宝帐号绑定,开启了手机动态口令,无线支付,和手机宝令三项功能。由于可以从淘宝或者支付宝登录,因此设定了70bit以上的高强度密码,1年更换一次。支付密码强度略弱,是30bit级别的,一年更换一次。支付宝账户安全等级高。使用支付宝的系统包括两台电脑和一台手机,一台是linux,一台是受限windows,只安装特定软件,不浏览和安装风险网页。总体来说,这个安全结构在支付宝用户中都是有数的。 风险在于支付宝手机客户端上,贝壳在评估的时候发现,支付宝手机客户端可以记录密码。这是一个非常具有风险的事情。因此贝壳模拟评估了一下,假如你丢失了手机,会发生什么事情。 低于200的支付 首先,由于支付宝客户端保存了密码,因此你可以很容易的登录支付宝。上面有绑定快捷支付的话(这是贝壳的常态,相信也有很多人有绑定,或者账户内有余额),在200以下就可以直接支付给对方,不需要任何额外验证。贝壳绑定的浦发银行发出了提款警告,但是很可惜,由于手机在恶意者手上,这一行为没有任何用处。 当然,常识告诉我们,如果你丢了个手机只损失200,这个问题可以忽略不计。 超过200的支付 如果超过200,则需要支付密码和手机验证码。在这个例子中,手机验证码是没有用处了,主要的保护就在支付密码上。然而,支付宝客户端具有找回支付密码的功能。幸好,他是基于身份证的。贝壳的身份证不是每个人都知道,因此在超过200的时候是安全的。 是否还有可能,从支付宝中恢复原始密码呢?因为有原始密码,就可以用网页访问支付宝,使用手机来恢复支付密码。关于这点,直到撰文为止,贝壳没有确认。 然而,问题其实远比这个简单。在没有支付宝密码的情况下。你可以申请忘记密码。然后支付宝会要求你输入你的账号来恢复密码。帐号?我记得在支付宝客户端上有记录。。。果然,输入帐号后,贝壳收到了支付宝的验证码。输入验证码后,贝壳重设了支付宝密码。在这一过程中,贝壳绑定的邮箱收到了警告——不过依然很可惜,唯一能够即时提示的手机现在在恶意者手中,主人一无所觉。 然后就是很没有新意的重设支付密码过程,借助手里的手机,我们完整的得到了整个支付宝的所有权,并且可以提光绑定了快捷支付的整张信用卡。在这里的唯一阻碍就是信用卡开卡行的支付限额。超过限额后需要使用密码和手机验证码来解除(浦发),手机验证码可以无视,密码是未知的。 结论 粗算了一下,丢一台手机,在一个小时内没有察觉,大约会造成4000元-4500元的损失,这还没有算手机。如果发卡行没有设定限额,最高大约是10W元。 我们来细数一下,整个过程里面的问题。 手机客户端不应当保存用户名密码,尤其是涉及资金的问题 对于频繁登录的问题,可以允许客户绑定一个手机token来解决。token等效于密码,但是不能做所有涉密操作,不能修改安全性,找回密码等。客户需要可以通过安全手段查看当前有多少个手机绑定了token,并且可以删除。贝壳之所以认为支付宝的系统有弱点,就是因为找遍整个支付宝系统,找不到删除token的地方。不能删除的token等于没用。 丢失密码的找回需要更加慎重 单纯的手机找回密码是有风险的,当然,单纯的邮箱找回也有。一种方法是同时验证手机和邮箱可以立刻找回密码,否则需要等待一定时间(例如几个小时,等待主人发现手机丢失)。 但是这仍然有风险。一般android里都会绑定邮件接收吧,借助这个很容易收到邮件。设计一个安全的密码找回方案并不是那么容易的,看来只有多等几个小时的方案略安全一些了。 同时这里也提醒一下。如果你在银行挂失银行卡找回密码的时候,觉得业务很方便。贝壳建议你立刻更换银行。在找回密码时越麻烦的银行,才是越安全的。 基于手机的核心验证体系 这是关键中的关键。我们可能会设计一个安全机制,里面有一步两步三步,必须全部通过才能操作资金。然而实际使用中,如果这三步都是依赖于同一个设备,那就对安全性没有任何提升——没有人敢保证手机不会丢失吧。钱包丢失最多损失几百,手机丢失呢? 目前,整个网银系统(不止是支付宝)都越来越多的依赖于手机。在手机越来越智能的今天,其可靠性实际上正在变差。手机可能丢失,也可能被安装恶意软件(尤其是root/越狱过的手机)。我们可以列出当手机丢失,或者安装了高权限的恶意软件时,会发生的安全问题。 个人信息泄密,包括朋友通讯方式,备忘,生日,身份证号码,家庭地址等。其中有些就涉及安全。 支付宝密码和支付密码可以重设(即,泄露)。 宝令丢失。 网银验证码无意义。 支付宝警告无意义。 网银警告无意义。 实际上,这不是支付宝的问题,而是用户在选择和设计自己的安全系统时,无意中造成的问题。 解决方案 暂时还没有太好的方案。 首先期待支付宝将手机登录改为token,取消密码保存,隐藏用户名,用户可以删除token,以解决直观的威胁。 期待手机丢失时快速发现的应用/功能。如果能在5-10分钟内停机,可以有效的解决手机丢失造成的风险。(贝壳向中国移动确认了,当手机停机后,是不能收取短信的) 当确实发生手机丢失时,应当首先立刻停机(因为停机速度快),然后向银行挂失(凡是绑定了手机的银行都要),然后以最快速度修改所有密码。 涉及资金的系统要多考虑一下,设计安全结构的时候要注意,如果有多于一个的方法进入系统,安全性决定于最弱的那个系统。如果所有步骤的安全性都依赖于手机,那么要考虑,丢了手机的时候会发生什么。

速度对比

Dec 29, 2012 - 4 minute read - Comments

引用 +------------+----------+-------------+------------+-------------+-------------+ |bps |B/s |network |storage |port |bus | +------------+----------+-------------+------------+-------------+-------------+ |56/48K |5.6/4.8K |Modem 56k | | | | +------------+----------+-------------+------------+-------------+-------------+ |57.6/28.8K |7.2/3.6K |GPRS | | | | +------------+----------+-------------+------------+-------------+-------------+ |236.8/236.8K|29.6/29.6K|EDGE (2.75G) | | | | +------------+----------+-------------+------------+-------------+-------------+ |1M |125K |Bluetooth 1.1| | | | +------------+----------+-------------+------------+-------------+-------------+ |1536K |192K | | |USB low speed| | +------------+----------+-------------+------------+-------------+-------------+ |1,536/512K |192/64K |ADSL (G.Lite)| | | | +------------+----------+-------------+------------+-------------+-------------+ |3M |375k |Bluetooth 2.0| | | | +------------+----------+-------------+------------+-------------+-------------+ |10M |1.25M |10BASE-T

异常和错误的几条军规

Nov 27, 2012 - 1 minute read - Comments

如果处理不了,就地崩溃,留尸不埋,供后人评价。 偷偷埋尸,100军棍。处理不了偷偷埋尸,拉出去先轮后杀。 忽略错误只有两种合法情况。 逻辑上可以忽略,记log,忽略。 逻辑上期待异常,不记log,忽略。 逻辑上不可以忽略的忽略,100军棍。 逻辑上可以忽略,没有记log,50军棍。 错误在函数间传递的唯一理由,是可以期待别人那里有个错误处理函数,能够对的上这个错误。 没人处理错误的乱传递,20军棍。 该你处理的,处理,不该你处理的,别乱处理。 乱处理错误的,先轮后杀。

python环境部署

Nov 22, 2012 - 1 minute read - Comments

abstract 本文的目的,在于教授使用virtualenv创立python环境,对环境的管理和使用,以及代码和部署的用法范例。在阅读完本文后,你应当可以。 创立,部署,管理virtualenv环境 使用virtualenv环境进行编码 virtualenv环境建立 virtualenv是python的虚环境管理包,他的主要目的是为了隔离环境。其中包含以下两个范畴。 在虚环境中安装包,不需要对系统进行修改,不会对系统造成污染。 在系统中安装的包,不会对虚环境造成污染。这主要是出于版本安全考虑。 因此,virtualenv默认会阻止你使用系统中安装的包。要解决这个问题,需要在建立虚拟环境时指定参数–system-site-packages。 virtualenv的环境可以通过执行virtualenv path加以建立。当建立完成后不可移动,需要一些特殊调整,使用参数–relocatable对此没有帮助。 virtualenv环境的激活和反激活 virtualenv环境是通过替换系统环境变量工作的。在激活后会替换系统的提示符,提示你进入环境。一般我们使用source \$VIRTUALENVPATH/bin/activate来激活。激活后直接执行deactivate反激活。 virtualenv替换系统环境变量的方式是在path前加入virtualenv的bin路径,使自己的python优于系统python执行。同时替换pythonhome,变更lib查找路径。因此,对于某些可以指定pythonhome的应用(例如网络部署),直接指定pythonpath为virtualenv路径即可。 注意,由于virtualenv的工作方式,因此当你执行su/sudo bash后,virtualenv环境都有可能消失,但是提示符仍旧生效。建议通过sudo执行脚本,脚本内进行source比较安全。或者直接sudo目标程序也可以,不要新建上下文。 如果需要保持持续的环境激活,可以将source \$VIRTUALENVPATH/bin/activate加入~/.bashrc。 当virtualenv激活后,后续的pip安装和python使用都会使用virtualenv内的版本。因此下文未经特殊说明,都是指在激活环境后进行操作。 virtualenv环境的管理 主要包括两种手段,安装和删除。一般使用pip install package name进行安装。pip uninstall package name进行删除。 virtualenv环境的保存和恢复 virtualenv环境可以保存和恢复。所谓保存和恢复,是指在安装过包的环境中保存包列表(和具体版本),在未安装(或版本错误)的环境中启用。 一般通过pip freeze > filename进行保存。在目标机器上执行pip install -r filename进行恢复。

python入门指引

Nov 19, 2012 - 1 minute read - Comments

前言 其实我也不知道python怎么入门,由我来写这个真的不是很合适。我学python是直接找了dive into python来看。然后照着写了几个例子。大概两天后,就能磕磕绊绊的上路了。就好像拿筷子,都不记得怎么学会的拿筷子,怎么来教人呢? 不过最近在python-cn的列表里面,我大概连续数周都持续看到“python入门看哪本教程比较好”,实在是不堪其扰。干脆就写个简单的guide,有心的人自己看。没心的——那我也没办法了。 基本知识 首先,你要了解一个事情。很多你不会的东西并不属于python。例如你不知道网络通讯的流程,你不知道文件的权限和打开标志用法,你不知道fork和stdin/stdout的关系。这些python教不会你。如果你缺乏这些和语言/库无关的相关知识,请自行补课。如果你缺乏计算机基础理论,请自行补课。 因此不要随便给我发邮件/留言/咨询,为什么这个问题在python里无法解决。为什么python无法所见即所得,为什么python无法热部署,为什么python无法用于嵌入式开发。在问这个问题之前,请先确认“这是一个python的问题”。例如GIL,或者脑残lambda。如果你不确定,请自己搜索一下相关的文章,确认一下。在提问前,看看“提问的智慧”。如果你确实搜过了,找不到,那就问吧,没办法。 入门 在网络上,python入门的两大基础书籍分别是(后面有朋友补充了一本,我也加上): A Byte of Python 中文版 Dive Into Python 中文版 Learn Python The Hard Way, 2nd Edition 中文版 后面基本就是看python-doc,我推荐你跳过一堆有的没的,直接看Library Reference。python本身就是易读性极强的代码,文档又相当漂亮,内置库又全。大部分情况下,python-doc都应当能解决你的问题。 web web是程序员的一大去向。python程序员入门必须要过的一个框架就是django。不要纠结了,django在python社区中名气太大,用的人太多。因此入门材料是最多的,社区最大,门槛最低。如果你要入门web,必然从django开始。在不熟悉python的情况下,我不推荐你贸然从其他框架开始入门。 当然,如果你已经熟悉python了,考虑入门web框架,可以参考专精一节。 爬虫 python下说到爬虫开发,入门首选Scrapy。原因和上面一样,社区最大,用的人最多。好不好用就见仁见智了。反正我的所有爬虫框架都是用自己基于gevent写的库。 ui python的ui框架也很多,很复杂。同样,如果是入门,我建议从qt的两个框架,pyqt和pyside开始入门。关于这两家的恩怨我就不多废话了。 专精 所谓专精,是指使用python在特定工作上。我们基本分为几个领域。 系统和部署 virtualenv:基本凡是在商用环境中部署的,建议都用这个。可以将python自带在源码里面,避免迁移/集成问题。 python-daemon:写daemon的时候比较方便。 网络 说到网络,基本就是除web外。 twisted:非常强大的网络库,各种协议支持全面,不过reactor模式真是纠结。 gevent:异步协程模式的网络库。 Scapy:强大的网络库,基本啥都能干。 pyzmq:我一直不觉得zeromq是一个mq。我觉得他是一个抽象网络层。 web容器 python web框架的一大特点,是容器/框架/ORM/template可以分开自己玩。 注意,容器和框架是两码事情。容器是python web运行的环境,框架是解析环境的玩意。两者间一般都使用wsgi接口进行连接。这是python的标准做法,fastcgi/scgi也会被转换为wsgi进行连接。但是也不是没有其他选择。一般我们有以下模式: cgi:python-doc中自带了cgi模块。 mod_python:embed in apache。 下面是wsgi接口的容器。wsgi的优点在于我们可以在这些容器上运行任意一款支持wsgi的框架。 flup:支持提供fastcgi, scgi, AJP接口,web server可以用这三种协议进行连接。 Google App Engine:PaaS服务。 Gunicorn:直接提供http服务。 mod_wsgi:使用内部协议和apache集成。 twisted:直接提供http服务。 tornado:直接提供http服务。 uWSGI:使用内部协议和nginx集成。 werkzeug:直接提供http服务。

老大啊,你这是什么鬼名字

Nov 3, 2012 - 1 minute read - Comments

sbcl 不知道大家用没用过common lisp,这是一种语言,最早是为了计算理论而生的。这种语言以规模大,难掌握,实现多,标准不统一而著称。 Steel Bank Common Lisp,简称sbcl,就是其中一种实现。他派生于SMUCL,是目前为止我看到的最好的开源实现。反正我在求解N多问题的时候,sbcl在速度和内存占用比上的表现相当抢眼。在lisp系列中称第一,和go这种静态语言相比也不遑多让。 但是每次我看到这个缩写都忍不住想吐槽,这是什么鬼名字啊。SB Common Lisp? debian 大家也许听过,也许没听过,debian社区曾经为了中文名字的事情争吵过。 从我看到的材料上看,很多人对debian的默认念法是——大便。。。 lua 我就不吐槽了,号称屌丝语言。 LZ不哭,站起来lua。 go google的奇葩语言。每次我要查某个用法的时候,都很郁闷。为什么呢?因为几乎所有的网页都命中”go”。 以StartProcess为例,我这里搜素go StartProcess的第一个命中在MSDN,微软有个API就叫StartProcess。再后面就是财经新闻。在很后面才能看到go的API。 etc IT界还有什么奇怪的名字?

异常之殇

Oct 30, 2012 - 1 minute read - Comments

异常之殇 辗转开解 辗转开解(stack unwinding)说的其实是这么一个现象。当执行流从深层向浅层转移时,深层调用所产生的栈上对象(stack object)需要销毁,资源需要释放。对于面对对象语言而言,往往就会执行到析构函数。 辗转开解中的异常 辗转开解真正令人迷惑之处在于,如果在析构函数中发生错误怎么办?在异常处理中发生异常,我们可以继续向上抛出。但是在辗转开解代码中出现异常,上层应当收到两个异常呢?还是一个? 无论是哪种可能,都没有完美自恰的符合直觉,因此这一般是一个未定义的行为。在C++中,进程会整个彻底崩溃掉的。因此,千万不要在析构函数内抛出(或者可能抛出)异常。 如果分离析构和资源销毁 一种做法是,在析构时不做资源销毁,转而提供专门的函数来执行资源销毁过程。析构只处理简单的delete等操作。然而这种做法的杯具在于,你在任何时候,一旦使用对象,都必须使用finally来保证销毁函数的调用。在发生异常时,栈上对象的辗转开解是自动的,析构函数的调用也是自动的,但是销毁函数的调用就是手工的了。 拷贝构造和隐式转换 和构造相反,对于构造函数,我们不能限制异常使用。你必须捕获构造函数的异常。 假如构造函数出了错 普通函数出错,你有两种选择。1. 异常。2. 返回值。构造函数出错,是没有选项2的。因此构造函数凡是出错必定异常。 而如果构造函数可能出错,而你期望捕获他,你就不能栈上构造一个对象出来。因为这会导致栈上对象的作用域被限定在捕获他所用的try块之内。 分离构造的尝试 和析构函数类似,我们可以尝试在构造函数外,提供一个构造函数,来替代构造的初始化过程。这样可以很大程度上保证构造函数不出错。 然而,首先,这样的代码就会变的复杂。每次构造函数完成调用后,都必须调用初始化函数。而且,有两种特殊的构造函数你不可能使用这种方法来解决。 拷贝构造和隐式转换 是的,这两种构造函数分别叫做拷贝构造(copy construct)和隐式转换(implicit casting)。我们举例来说。如果你在函数内建立了一个对象,你希望返回这个对象,怎么做呢?第一个思路是引用返回。不幸的是,要做引用返回,这个对象必须是堆上对象,而非栈上对象。因为栈上对象在返回后会销毁掉。如果要返回栈上对象,唯一靠谱的方案是先将对象复制到堆上,然后再复制到调用者的栈里。 C++中有一类特殊的优化,叫做对象返回优化。当编译器察觉到你需要返回栈上对象时,那么编译器会直接获得调用者栈里的对象地址。这样可以避免两次的拷贝过程。然而,如果没有对象返回优化(或者没有识别出来),那么就需要两次复制以保证正确性。而C++里,默认的复制过程是内存拷贝。 对于很多对象,内存拷贝是错误的行为。例如字符串,一种字符串的加速方法叫做共享内存字符串。两个字符串对象会共享一个内存块,以避免重复内容的开销。直到其中一块需要修改时,复制才真的继续。对于这种情况,直接拷贝会明显的导致错误。因此C++有一种特殊的构造函数,叫做拷贝构造。 在拷贝构造的时候,调用是由C++隐式发生的,你根本没有先构造,再调用的机会和权力。因此,试图分离构造在技术上不可行。 隐式转换是另一种情况。当你传递的参数和实际被赋值对象的类型不一致时(例如调用了某个函数,其参数类型不一致),C++会试图将你的对象转换为目标对象。如果是内部类型,这个被称为内部隐式转换。unsigned char可以被无错的转换为unsigned long,这个大家都知道。但是如果是对象,转换行为就需要由构造函数定义,这个叫做隐式转换构造函数。 另外,隐式转换也是OO中的一大问题。我强烈建议你用explicit禁用所有隐式转换,改为显式转换。这会费一点事,但是却可以避免很多问题。 分离构造/析构的邪恶之处 ZMQ的作者曾经吐槽过这种在构造/析构之外再定义初始化/清除代码的努力。他的观点是,如果万一在构造函数中加入了代码,会引起半构造现象。为了解决这个问题,会使得整个类带上状态。我在上面已经假定这件事情不会发生了,否则代码会更加复杂,问题也更加严重。 二次异常 是的,你不应当在异常处理代码中抛出异常。当然,这里的异常指的是你的异常处理代码不应当发生异常。经过逻辑判定,当前的异常应当由更上层处理的情况不在此列。 如果在异常处理中抛出异常,很可能导致的结果就是异常处理没有完成。而未完成的异常处理会发生什么问题,那只有天晓得。这个在任何带有异常系统的语言中都是成立的。