分析

Level2的地址:http://www.pythonchallenge.com/pc/def/ocr.html

文字提示MAYBE they are in the page source

查看网页的源码,发现注释的部分:

find rare characters in the mess below:

需要从那段内容中找出稀少的字符。

解决

text = ‘’’
      …
       ‘’’
result = {}
for x in text:
    result[x] = result.get(x,0) + 1
print(result)

输出:

{'(': 6154, ')': 6186, '*': 6034, '+': 6066, 'l': 1, 'i': 1, ' ': 4880, '!': 6079, '#': 6115, '$': 6046, '%': 6104, '&': 6043, 'e': 1, 'y': 1, '{': 6046, '}': 6105, 'q': 1, 't': 1, 'u': 1, 'a': 1, '\n': 1221, '@': 6157, '[': 6108, ']': 6152, '^': 6030, '_': 6112}

发现最少的都是个数为1的字母,这样稍加改变:

result = []
for x in text:
    if x.isalpha():
        result.append(x)
print(''.join(result))

输出:

equality

其他的解决方法

按照惯例,查看解决方法:http://www.pythonchallenge.com/pcc/def/ocr.html

Level 1的地址:http://www.pythonchallenge.com/pc/def/map.html

分析

网页的标题为What about making trans?,然后再看图片:

K -> M
O -> Q
E -> G

应该是一个类似凯撒密码的字母移位,每个字母向后移动两位,而要处理的就是下面那段文字。

解决

代码如下:

'''
Level 1
'''
text = '''
g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr   gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle    qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj.
'''
trans = ''
for x in text:
    trans += chr((ord(x) - ord('a') + 2)%26 + ord('a')) if x.isalpha() else x
print(trans)

输出结果:

i hope you didnt translate it by hand. thats what computers are for. doing it in
by hand is inefficient and that's why this text is so long. using string.maketrans() 
is recommended. now apply on the url.

根据转化后的信息,处理url中的map进行同样的转换,获得新的url:http://www.pythonchallenge.com/pc/def/ocr.html,顺利进入下一关。

str.maketrans()

等等,仔细看转换后的信息,推荐使用string.maketrans()方法。

查找python3在线文档,发现在python3.4后有所变化。

代码如下:

''
use str.maketrans()
'''

import string

text = '''
g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr   gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle    qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj.
'''

dlist = string.ascii_lowercase
table = str.maketrans(dlist,dlist[2:] + dlist[:2])
print(text.translate(table))

首先,使用str.maketrans()方法生成一个映射表,从[A-Z]映射为[C-A],打印table

{97: 99, 98: 100, 99: 101, 100: 102, 101: 103, 102: 104, 103: 105, 104: 106, 105: 107, 106: 108, 107: 109, 108: 110, 109: 111, 110: 112, 111: 113, 112: 114, 113: 115, 114: 116, 115: 117, 116: 118, 117: 119, 118: 120, 119: 121, 120: 122, 121: 97, 122: 98}

然后,调用translate()方法,将映射表作为参数。最终获取想要的结果。

str.maketrans()的第一个和第二个参数长度必须相同,转换的时候一一对应;如果有第三个参数,将会转换为None

mm = 'abcdefg'
tb1 = str.maketrans('abcd','1234')
tb2 = str.maketrans('abcd','1234','ef')
print(mm.translate(tb1))
print(mm.translate(tb2))

输出结果:

1234efg
1234g

其他的解决方法

进入下一个Level的页面,有一条tips,将当前url中的pc改为pcc就可以查看前一个Level的解决方法了。

http://www.pythonchallenge.com/pcc/def/ocr.html

参考资料:

Python documentation

引子

最近空余时间,开始学习python,发现一个很有意思的网站:pythonchallenge。目前有33个挑战的级别,打算写一个系列的博客,记录下来学习的过程。那就从零开始吧!

Level 0

Level 0的地址:http://www.pythonchallenge.com/pc/def/0.html

一张图片,上面写着2的38次方

Hint: try to change the URL address.

使用python求2的38次方的值:

2**38

或者:

import math
pow(2,38)

或者:

1 << 38

得到结果:274877906944

根据提示,修改url为:http://www.pythonchallenge.com/pc/def/274877906944.html

这样就进入下一关了, ^_^)

参考资料:

深入 Python 3

在iOS开发中,经常需要抓包来查看网络请求、应答的情况,例如坚持服务端应答数据、服务端应答速度、客户端发生请求、流量检测、安全性检测等等。不论代码内如何实现,抓包能够最好的证实一切,往往可以更快地定位问题,解决问题。下面总结几种常用的抓包方法。

使用charles抓包

在mac下,charles是一个非常好用的抓取http/https请求的工具。

限制条件:

  • 需要mac与iOS设备连接相同的无线网络
  • 只能抓取http/https的数据包
  • 无法抓取2G/3G/4G网络下得数据

[注]:更多关于charles的使用方法参照http://www.charlesproxy.com/documentation/

使用RVI(Remote Virtual Interface)+wireshark抓包

在iOS5以后,Apple为iOS引入了RVI(Remote Virtual Interface),只要设备通过USB连接到Mac,就可以虚拟出一个远程端口,这样就可以在Mac上使用Wireshark抓取这个远程虚拟端口的数据包了。

限制条件:

  • 支持的设备系统iOS5以及之后

使用tcpdump命令抓包

限制条件:

  • 需要iOS设备越狱

小结

以上是平时常用到得几种抓包方法,各有优缺点,可以根据需要选择最方便的方法。

参考资料

http://www.charlesproxy.com/

http://www.charlesproxy.com/documentation/

http://www.wireshark.org/

iOS7更新后,当倾斜手机的时候,会看到屏幕上的背景图片会随着手机的倾斜度而移动,产生视差。刚开始更新的时候,还以为是自己的错觉,--!。

UIMotionEffect就像它的名字一样,处理motion effect。UIMotionEffect是一个抽象的基类,子类通过重写keyPathsAndRelativeValuesForViewerOffset:方法,当检测到动作的时候

苹果提供了一个子类UIInterpolatingMotionEffect,通过它我们可以实现对设备水平和竖直方向倾斜。

UIInterpolatingMotionEffect *horizontalMotionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
horizontalMotionEffect.minimumRelativeValue = @(-50);
horizontalMotionEffect.maximumRelativeValue = @(50);
[redView addMotionEffect:horizontalMotionEffect];

http://www.teehanlax.com/blog/introduction-to-uimotioneffect/ https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIMotionEffect_class/Reference/Reference.html#//apple_ref/doc/uid/TP40013376 https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIMotionEffectGroup_class/Reference/Reference.html#//apple_ref/doc/uid/TP40013378

平时调试程序的时候,经常会使用NSLog打印出来。当有CGPoint、CGSize、CGRect对象要打印时,一般要写成下面的方式:

CGPoint point = CGPointMake(0, 20);
NSLog(@"Point: x=%f, y=%f", point.x, point.y);

CGSize size = CGSizeMake(200, 100);
NSLog(@"Size: w=%f, h=%f", size.width, size.height);

CGRect rect = CGRectMake(0, 0, 200, 100);
NSLog(@"Rect: x=%f, y=%f, w=%f, h=%f", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);

今天看到一篇文章:How to Use NSLog to Debug CGRect and CGPoint,才了解到有一些其他方便的方法。

CGPoint point = CGPointMake(0, 20);
NSLog(@"Point: %@", NSStringFromCGPoint(point));

CGSize size = CGSizeMake(200, 100);
NSLog(@"Size: %@", NSStringFromCGSize(size));

CGRect rect = CGRectMake(0, 0, 200, 100);
NSLog(@"Rect: %@", NSStringFromCGRect(rect));

打印结果:

Point: {0, 20}
Size: {200, 100}
Rect: \{\{0, 0\}, \{200, 100\}\}

Debug输出:

#ifdef DEBUG
    #define debug(format, ...) CFShow([NSString stringWithFormat:format, ## __VA_ARGS__]);
    #define debugAlert(format, ...)  {UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%s\n line: %d ", __PRETTY_FUNCTION__, __LINE__] message:[NSString stringWithFormat:format, ##__VA_ARGS__]  delegate:nil cancelButtonTitle:@"Done" otherButtonTitles:nil]; [alert show]; [alert release];}
#else
    #define debug(format, ...) 
    #define debugAlert(format, ...)
#endif

检测是否支持ARC:

#if __has_feature(objc_arc)
    // ARC
#else
    // No ARC
#endif

http://iosdevelopertips.com/debugging/remove-debug-code-for-release-build.html

http://iosdevelopertips.com/debugging/display-debug-information-in-uialertview.html

Object-C中的Category

Object-C中的Category,相信大家一定不会陌生。一般来说,我们可以用它来为一个类添加新的方法:

@interface NSString (NumberUtils)
- (BOOL)isNumeric; 
@end

@implementation NSString (NumberUtils) 
- (BOOL)isNumeric
{
    NSScanner *scanner = [NSScanner scannerWithString:self];
    return [scanner scanFloat:NULL]? [scanner isAtEnd]: NO;
}
@end

我们也可以Category中定义新的数据成员,但是不能够对它们使用synthesize。这是因为一个类的结构已经在编译器决定了,而Category是在运行期定义生成的,这样就没有办法改变类结构体中的ivars。

struct objc_class {  
    Class isa  OBJC_ISA_AVAILABILITY;  

    #if !__OBJC2__  
    Class super_class                                        OBJC2_UNAVAILABLE;  
    const charchar *name                                     OBJC2_UNAVAILABLE;  
    long version                                             OBJC2_UNAVAILABLE;  
    long info                                                OBJC2_UNAVAILABLE;  
    long instance_size                                       OBJC2_UNAVAILABLE;  
    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;  
    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;  
    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;  
    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;  
#endif  

} OBJC2_UNAVAILABLE;    

可以向下面这样定义:

@interface NSString (NumberUtils)
@property (nonatomic, readonly, getter=isNumeric) BOOL numeric;
@end

如果我们想为一个类真正添加一个数据成员,要怎么办呢?当然你可能会想到使用修饰者,封装出一个对象,包含这个类和想要添加的数据成员。但是那样要麻烦一些。

使用Associated Objects为一个分类添加数据成员

使用Runtime来解决这个问题。要使用的API:

 // 使用一个key值和关联策略来为一个对象设置一个关联的值
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);

objc_setAssociatedObject:使用一个key值和关联策略来为一个对象设置一个关联的值。类似NSDictionry,一个key值,对应一个value值。

key值必须是进程的生命周期内一个唯一、不变的id值。可以使用一个NSString对象作为一个key值。但是如果试图通过一个相同的字符串值,但是不同内存地址作为key值,可能不会获得预期的结果。一个更好的选择是定义一个static的指针作为key值。

下面一个例子:

@interface UIImage (Tagged)
@property (nonatomic, copy) NSString *tag;
@end    

#import <objc/runtime.h> 

static const void *ImageTagKey = &ImageTagKey;
@implementation UIImage (Tagged)

- (void)setTag:(NSSting *)tag
{
    objc_setAssociatedObject(self, ImageTagKey, tag, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)tag
{
    return objc_getAssociatedObject(self, ImageTagKey);
}
@end

这个例子中有一点点需要主要:

  • key值使用一个指针类型static const void * 。我们必须让这个指针初始化,否则它的值就会为NULL,但是我们不关心具体指向什么,只要它是唯一的,不变的。这里面,指针指向了自己,一个唯一、不变的值。

参考文章:

Objective-C Runtime Reference

Adding Properties to a Category Using Associated Objects

Associated Objects

技术类书籍

首先时技术类书籍:

  • 《从小工到专家——程序员修炼之道》
  • 《Head First 设计模式》
  • 《iOS 高级编程》
  • 《Python》

非技术类书籍

非技术类:

  • 《一个人的村庄》
  • 《1984》
  • 《少有人走的路》
  • 《自由在高处》
  • 《九种孤独》
  • 《天才在左,疯子在右》
  • 《猎命师传奇:卷二十》
  • 《上帝掷骰子吗》
  • 《沉默的大多数》
  • 《变身》、《新参者》