可可熊的窝

Category Archives: 编程相关

Ext2文件系统源代码分析(2)

IN:C, 编程相关   Tags:    Comments:2

xattr.h:

/*
  File: linux/ext2_xattr.h

  On-disk format of extended attributes for the ext2 filesystem.

  (C) 2001 Andreas Gruenbacher, <a .gruenbacher@computer.org>
*/

#include <linux /init.h>
#include </linux><linux /xattr.h>

/* Magic value in attribute blocks */
#define EXT2_XATTR_MAGIC                0xEA020000
//定义属性block中使用的魔数(一个标记,唯一的值)

/* Maximum number of references to one attribute block */
#define EXT2_XATTR_REFCOUNT_MAX         1024
//定义一个属性block

/* Name indexes */
#define EXT2_XATTR_INDEX_USER                   1
#define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS       2
#define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT      3
#define EXT2_XATTR_INDEX_TRUSTED                4
#define EXT2_XATTR_INDEX_LUSTRE                 5
#define EXT2_XATTR_INDEX_SECURITY               6

struct ext2_xattr_header {
        __le32  h_magic;        /* magic number for identification */
        __le32  h_refcount;     /* reference count */
        __le32  h_blocks;       /* number of disk blocks used */
        __le32  h_hash;         /* hash value of all attributes */
        __u32   h_reserved[4];  /* zero right now */
};
//__le32 h_magic; 标识码,为0xEA020000 

//__le32 h_refcount; 属性块被链接的数目 

//__le32 h_blocks; 用于扩展属性的块数 

//__le32 h_hash;  所有属性的哈希值 

//__u32 h_reserved[4]; 保留变量,目前为0

struct ext2_xattr_entry {
        __u8    e_name_len;     /* length of name */
        __u8    e_name_index;   /* attribute name index */
        __le16  e_value_offs;   /* offset in disk block of value */
        __le32  e_value_block;  /* disk block attribute is stored on (n/i) */
        __le32  e_value_size;   /* size of attribute value */
        __le32  e_hash;         /* hash value of name and value */
        char    e_name[0];      /* attribute name */
};

//__u8 e_name_len; 属性名长度 

//__u8 e_name_index; 属性名索引 

//__le16 e_value_offs; 属性值在值块中的偏移量 

//__le32 e_value_block;  保存属性值的块的块号 

//__le32 e_value_size;  属性值长度 

//__le32 e_hash;  属性名和值的哈希值 

//char e_name[0];  属性名

#define EXT2_XATTR_PAD_BITS             2
#define EXT2_XATTR_PAD          (1< <EXT2_XATTR_PAD_BITS)
#define EXT2_XATTR_ROUND                (EXT2_XATTR_PAD-1)
#define EXT2_XATTR_LEN(name_len) \
        (((name_len) + EXT2_XATTR_ROUND + \
        sizeof(struct ext2_xattr_entry)) & ~EXT2_XATTR_ROUND)
#define EXT2_XATTR_NEXT(entry) \
        ( (struct ext2_xattr_entry *)( \
          (char *)(entry) + EXT2_XATTR_LEN((entry)->e_name_len)) )
#define EXT2_XATTR_SIZE(size) \
        (((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND)

# ifdef CONFIG_EXT2_FS_XATTR
//当内核编译时指定使用xattr扩展属性时,xattr相关函数的申明

extern struct xattr_handler ext2_xattr_user_handler;
extern struct xattr_handler ext2_xattr_trusted_handler;
extern struct xattr_handler ext2_xattr_acl_access_handler;
extern struct xattr_handler ext2_xattr_acl_default_handler;
extern struct xattr_handler ext2_xattr_security_handler;

extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);

extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);

extern void ext2_xattr_delete_inode(struct inode *);
extern void ext2_xattr_put_super(struct super_block *);

extern int init_ext2_xattr(void);
extern void exit_ext2_xattr(void);

extern struct xattr_handler *ext2_xattr_handlers[];

# else  /* CONFIG_EXT2_FS_XATTR */

//当内核编译时未使用xattr扩展属性,xattr相关函数被置为空

static inline int
ext2_xattr_get(struct inode *inode, int name_index,
               const char *name, void *buffer, size_t size)
{
        return -EOPNOTSUPP;
}

static inline int
ext2_xattr_set(struct inode *inode, int name_index, const char *name,
               const void *value, size_t size, int flags)
{
        return -EOPNOTSUPP;
}

static inline void
ext2_xattr_delete_inode(struct inode *inode)
{
}

static inline void
ext2_xattr_put_super(struct super_block *sb)
{
}

static inline int
init_ext2_xattr(void)
{
        return 0;
}

static inline void
exit_ext2_xattr(void)
{
}

#define ext2_xattr_handlers NULL

# endif  /* CONFIG_EXT2_FS_XATTR */

#ifdef CONFIG_EXT2_FS_SECURITY
extern int ext2_init_security(struct inode *inode, struct inode *dir);
#else
static inline int ext2_init_security(struct inode *inode, struct inode *dir)
{
        return 0;
}
#endif

xip.h:

/*
 *  linux/fs/ext2/xip.h
 *
 * Copyright (C) 2005 IBM Corporation
 * Author: Carsten Otte (cotte@de.ibm.com)
 */

#ifdef CONFIG_EXT2_FS_XIP
//当内核编译时指定使用xip扩展属性时,xip相关操作的函数申明
extern void ext2_xip_verify_sb (struct super_block *);
extern int ext2_clear_xip_target (struct inode *, int);

static inline int ext2_use_xip (struct super_block *sb)
{
        struct ext2_sb_info *sbi = EXT2_SB(sb);
        return (sbi->s_mount_opt & EXT2_MOUNT_XIP);
}
struct page* ext2_get_xip_page (struct address_space *, sector_t, int);
#define mapping_is_xip(map) unlikely(map->a_ops->get_xip_page)
#else
//当内核编译时未指定使用xattr扩展属性时,置这些函数操作为空

#define mapping_is_xip(map)                     0
#define ext2_xip_verify_sb(sb)                  do { } while (0)
#define ext2_use_xip(sb)                        0
#define ext2_clear_xip_target(inode, chain)     0
#define ext2_get_xip_page                       NULL
#endif

05-05
2008

Ext2文件系统源代码分析(1)

IN:C, 编程相关   Tags:    Comments:0

acl.h:

/*
  File: fs/ext2/acl.h

  (C) 2001 Andreas Gruenbacher, <a .gruenbacher@computer.org>
*/

#include <linux /posix_acl_xattr.h>

//简单说一下acl(访问控制表),比传统的Linux具有更灵活的文件权限设定,ext2文件系统的扩展属性支持acl,这一点在编译的时候可以指定。
#define EXT2_ACL_VERSION        0x0001

//定义acl的版本;
typedef struct {
        __le16          e_tag;
        __le16          e_perm;
        __le32          e_id;
} ext2_acl_entry;
//__le16类型的定义:
//typedef __u16 __bitwise __le16;
//看起来比较复杂,其实(在x86平台下)只是一个unsigned short,__bitwise这个只是通过gcc的扩展使用sparse这个工具来进行代码检查。

//ext2_acl_entry定义访问控制项的结构体
//__le16          e_tag;   自身的使用者或組
//__le16          e_perm;  允许访问的
//__le32          e_id; 

typedef struct {
        __le16          e_tag;
        __le16          e_perm;
} ext2_acl_entry_short;
//定义访问控制项的简单结构;

typedef struct {
        __le32          a_version;
} ext2_acl_header;

//接下来两个函数分别用到了size_t与ssize_t对应在x86平台下分别是unsigned int与int
static inline size_t ext2_acl_size(int count)
{
        if (count < = 4) {
                return sizeof(ext2_acl_header) +
                       count * sizeof(ext2_acl_entry_short);
        } else {
                return sizeof(ext2_acl_header) +
                       4 * sizeof(ext2_acl_entry_short) +
                       (count - 4) * sizeof(ext2_acl_entry);
        }
}

//该函数用来计算acl的占用空间大小,当使用的acl多于4后剩余的acl使用完整的ext2_acl_entry来记录。
static inline int ext2_acl_count(size_t size)
{
        ssize_t s;
        size -= sizeof(ext2_acl_header);
        s = size - 4 * sizeof(ext2_acl_entry_short);
        if (s < 0) {
                if (size % sizeof(ext2_acl_entry_short))
                        return -1;
                return size / sizeof(ext2_acl_entry_short);
        } else {
                if (s % sizeof(ext2_acl_entry))
                        return -1;
                return s / sizeof(ext2_acl_entry) + 4;
        }
}
//该函数与上面的函数刚好相反
#ifdef CONFIG_EXT2_FS_POSIX_ACL

//当内核编译时指定使用ext2的acl属性时这里ext2_permission等函数被申明,否则这些函数被定义为空。
/* Value for inode->u.ext2_i.i_acl and inode->u.ext2_i.i_default_acl
   if the ACL has not been cached */
#define EXT2_ACL_NOT_CACHED ((void *)-1)

/* acl.c */
extern int ext2_permission (struct inode *, int, struct nameidata *);
extern int ext2_acl_chmod (struct inode *);
extern int ext2_init_acl (struct inode *, struct inode *);

#else
#include </linux><linux /sched.h>
#define ext2_permission NULL
#define ext2_get_acl    NULL
#define ext2_set_acl    NULL

static inline int
ext2_acl_chmod (struct inode *inode)
{
        return 0;
}

static inline int ext2_init_acl (struct inode *inode, struct inode *dir)
{
        return 0;
}
#endif

file.c:

/*
 *  linux/fs/ext2/file.c
 *
 * Copyright (C) 1992, 1993, 1994, 1995
 * Remy Card (card@masi.ibp.fr)
 * Laboratoire MASI - Institut Blaise Pascal
 * Universite Pierre et Marie Curie (Paris VI)
 *
 *  from
 *
 *  linux/fs/minix/file.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 *
 *  ext2 fs regular file handling primitives
 *
 *  64-bit file support on 64-bit platforms by Jakub Jelinek
 *      (jj@sunsite.ms.mff.cuni.cz)
 */

#include </linux><linux /time.h>
#include "ext2.h"
#include "xattr.h"
#include "acl.h"

/*
 * Called when filp is released. This happens when all file descriptors
 * for a single struct file are closed. Note that different open() calls
 * for the same file yield different struct file structures.
 */
static int ext2_release_file (struct inode * inode, struct file * filp)
{
        if (filp->f_mode & FMODE_WRITE) {
                mutex_lock(&EXT2_I(inode)->truncate_mutex);
                ext2_discard_reservation(inode);
                mutex_unlock(&EXT2_I(inode)->truncate_mutex);
        }
        return 0;
}

//该函数释放文件所使用的block,前提是该文件以"写"的模式被打开。
/*
 * We have mostly NULL's here: the current defaults are ok for
 * the ext2 filesystem.
 */
const struct file_operations ext2_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
        .write          = do_sync_write,
        .aio_read       = generic_file_aio_read,
        .aio_write      = generic_file_aio_write,
        .ioctl          = ext2_ioctl,
#ifdef CONFIG_COMPAT
        .compat_ioctl   = ext2_compat_ioctl,
#endif
        .mmap           = generic_file_mmap,
        .open           = generic_file_open,
        .release        = ext2_release_file,
        .fsync          = ext2_sync_file,
        .splice_read    = generic_file_splice_read,
        .splice_write   = generic_file_splice_write,
};

//ext2_file_operations这个结构体定义了上层(VFS)文件操作函数在ext2文件系统这一层中的具体实现函数。
//这里又用到了gcc的扩展使用.[index]这样的方式来初始化结构体,这样结构体中的成员就不会受到顺序的限制。
#ifdef CONFIG_EXT2_FS_XIP
const struct file_operations ext2_xip_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = xip_file_read,
        .write          = xip_file_write,
        .ioctl          = ext2_ioctl,
#ifdef CONFIG_COMPAT
        .compat_ioctl   = ext2_compat_ioctl,
#endif
        .mmap           = xip_file_mmap,
        .open           = generic_file_open,
        .release        = ext2_release_file,
        .fsync          = ext2_sync_file,
};
#endif

//ext2_xip_file_operations定义了使用xip(eXecute In Place)的文件操作函数
const struct inode_operations ext2_file_inode_operations = {
        .truncate       = ext2_truncate,
#ifdef CONFIG_EXT2_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
        .listxattr      = ext2_listxattr,
        .removexattr    = generic_removexattr,
#endif
        .setattr        = ext2_setattr,
        .permission     = ext2_permission,
};
//ext2_file_inode_operations定义了ext2中inode的文件操作函数。

05-05
2008

Ext2文件系统源代码分析(0)

IN:C, 编程相关   Tags:    Comments:0

Makefile:

#
# Makefile for the linux ext2-filesystem routines.
#

obj-$(CONFIG_EXT2_FS) += ext2.o

ext2-y := balloc.o dir.o file.o fsync.o ialloc.o inode.o \
          ioctl.o namei.o super.o symlink.o

ext2-$(CONFIG_EXT2_FS_XATTR)     += xattr.o xattr_user.o xattr_trusted.o
ext2-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o
ext2-$(CONFIG_EXT2_FS_SECURITY)  += xattr_security.o
ext2-$(CONFIG_EXT2_FS_XIP)       += xip.o

obj-$(CONFIG_EXT2_FS)指定编译生成的目标文件,CONFIG_EXT2_FS变量在配置内核时指定,有三个选项:y,m,x分别代表编译,以模块方式编译,不编译。

ext2-y指定了编译ext2.o时所需要同时编译的其它文件。

下面四个是ext2文件系统的一些扩展属性,也是在编译内核时配置是否使用。

ext2.h:

#include <linux /fs.h>
#include </linux><linux /ext2_fs.h>

/*
 * ext2 mount options
 */
struct ext2_mount_options {
        unsigned long s_mount_opt;
        uid_t s_resuid;
        gid_t s_resgid;
};
//这里定义了一个ext2文件系统挂载时所使用的一些选项,uid_t,gid_t在i386上是unsigned int。
//s_mount_opt:安装选项
//s_resuid:可以使用保留块的用户id
//s_resgid:可以使用保留块的用户组id

/*
 * second extended file system inode data in memory
 */
struct ext2_inode_info {
        __le32  i_data[15];
        __u32   i_flags;
        __u32   i_faddr;
        __u8    i_frag_no;
        __u8    i_frag_size;
        __u16   i_state;
        __u32   i_file_acl;
        __u32   i_dir_acl;
        __u32   i_dtime;

        /*
         * i_block_group is the number of the block group which contains
         * this file's inode.  Constant across the lifetime of the inode,
         * it is ued for making block allocation decisions - we try to
         * place a file's data blocks near its inode block, and new inodes
         * near to their parent directory's inode.
         */
        __u32   i_block_group;

        /* block reservation info */
        struct ext2_block_alloc_info *i_block_alloc_info;

        __u32   i_dir_start_lookup;
#ifdef CONFIG_EXT2_FS_XATTR
        /*
         * Extended attributes can be read independently of the main file
         * data. Taking i_mutex even when reading would cause contention
         * between readers of EAs and writers of regular file data, so
         * instead we synchronize on xattr_sem when reading or changing
         * EAs.
         */
        struct rw_semaphore xattr_sem;
#endif
#ifdef CONFIG_EXT2_FS_POSIX_ACL
        struct posix_acl        *i_acl;
        struct posix_acl        *i_default_acl;
#endif
        rwlock_t i_meta_lock;

        /*
         * truncate_mutex is for serialising ext2_truncate() against
         * ext2_getblock().  It also protects the internals of the inode's
         * reservation data structures: ext2_reserve_window and
         * ext2_reserve_window_node.
         */
        struct mutex truncate_mutex;
        struct inode    vfs_inode;
        struct list_head i_orphan;      /* unlinked but open inodes */
};

//ext2_inode_info这个结构体定义了inode在内存中存放的信息。
//__le32  i_data[15];  __le32是带bitwise属性的unsigned int;数据块指针数组
//__u32   i_flags;  __u32是unsigned int;文件标志
//__u32   i_faddr;  fragment地址
//__u8    i_frag_no;  fragment号
//__u8    i_frag_size;  fragment大小
//__u16   i_state;
//__u32   i_file_acl;  文件访问控制链表
//__u32   i_dir_acl;  目录访问控制链表
//__u32   i_dtime;  文件删除时间
//__u32   i_block_group;  inode所在组号
//struct ext2_block_alloc_info *i_block_alloc_info;  block保留信息

/*
 * Inode dynamic state flags
 */
#define EXT2_STATE_NEW                  0x00000001 /* inode is newly created */

/*
 * Function prototypes
 */

/*
 * Ok, these declarations are also in </linux><linux /kernel.h> but none of the
 * ext2 source programs needs to include it so they are duplicated here.
 */

static inline struct ext2_inode_info *EXT2_I(struct inode *inode)
{
        return container_of(inode, struct ext2_inode_info, vfs_inode);
}
//EXT2_I函数利用到了内核中经常使用的一个宏:container_of,它的参数为inode指针,返回一个ext2_inode_info的指针,也就是inode所在结构体的地址。
//container_of在linux-2.6.24/include/linux/kernel.h里定义为:
//#define container_of(ptr, type, member) ({                      \
       const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
       (type *)( (char *)__mptr - offsetof(type,member) );})

//这个宏的原理其实很简单就是利用结构体中某个元素的地址减去该元素相对于结构体的偏移量,得到结构体的地址。

//offsetof在linux-2.6.24/include/linux/stddef.h中定义为:
//#undef offsetof
//#ifdef __compiler_offsetof
//#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
//#else
//#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
//#endif

//接下来这这些是定义在ext2其它文件中的函数的申明。
/* balloc.c */
extern int ext2_bg_has_super(struct super_block *sb, int group);
extern unsigned long ext2_bg_num_gdb(struct super_block *sb, int group);
extern ext2_fsblk_t ext2_new_block(struct inode *, unsigned long, int *);
extern ext2_fsblk_t ext2_new_blocks(struct inode *, unsigned long,
                                unsigned long *, int *);
extern void ext2_free_blocks (struct inode *, unsigned long,
                              unsigned long);
extern unsigned long ext2_count_free_blocks (struct super_block *);
extern unsigned long ext2_count_dirs (struct super_block *);
extern void ext2_check_blocks_bitmap (struct super_block *);
extern struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
                                                    unsigned int block_group,
                                                    struct buffer_head ** bh);
extern void ext2_discard_reservation (struct inode *);
extern int ext2_should_retry_alloc(struct super_block *sb, int *retries);
extern void ext2_init_block_alloc_info(struct inode *);
extern void ext2_rsv_window_add(struct super_block *sb, struct ext2_reserve_window_node *rsv);

/* dir.c */
extern int ext2_add_link (struct dentry *, struct inode *);
extern ino_t ext2_inode_by_name(struct inode *, struct dentry *);
extern int ext2_make_empty(struct inode *, struct inode *);
extern struct ext2_dir_entry_2 * ext2_find_entry (struct inode *,struct dentry *, struct page **);
extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
extern int ext2_empty_dir (struct inode *);
extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *);

/* fsync.c */
extern int ext2_sync_file (struct file *, struct dentry *, int);

/* ialloc.c */
extern struct inode * ext2_new_inode (struct inode *, int);
extern void ext2_free_inode (struct inode *);
extern unsigned long ext2_count_free_inodes (struct super_block *);
extern void ext2_check_inodes_bitmap (struct super_block *);
extern unsigned long ext2_count_free (struct buffer_head *, unsigned);

/* inode.c */
extern void ext2_read_inode (struct inode *);
extern int ext2_write_inode (struct inode *, int);
extern void ext2_put_inode (struct inode *);
extern void ext2_delete_inode (struct inode *);
extern int ext2_sync_inode (struct inode *);
extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
extern void ext2_truncate (struct inode *);
extern int ext2_setattr (struct dentry *, struct iattr *);
extern void ext2_set_inode_flags(struct inode *inode);
extern void ext2_get_inode_flags(struct ext2_inode_info *);
int __ext2_write_begin(struct file *file, struct address_space *mapping,
                loff_t pos, unsigned len, unsigned flags,
                struct page **pagep, void **fsdata);

/* ioctl.c */
extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
                       unsigned long);
extern long ext2_compat_ioctl(struct file *, unsigned int, unsigned long);

/* namei.c */
struct dentry *ext2_get_parent(struct dentry *child);

/* super.c */
extern void ext2_error (struct super_block *, const char *, const char *, ...)
        __attribute__ ((format (printf, 3, 4)));
extern void ext2_warning (struct super_block *, const char *, const char *, ...)
        __attribute__ ((format (printf, 3, 4)));
extern void ext2_update_dynamic_rev (struct super_block *sb);
extern void ext2_write_super (struct super_block *);

/*
 * Inodes and files operations
 */

/* dir.c */
extern const struct file_operations ext2_dir_operations;

/* file.c */
extern const struct inode_operations ext2_file_inode_operations;
extern const struct file_operations ext2_file_operations;
extern const struct file_operations ext2_xip_file_operations;

/* inode.c */
extern const struct address_space_operations ext2_aops;
extern const struct address_space_operations ext2_aops_xip;
extern const struct address_space_operations ext2_nobh_aops;

/* namei.c */
extern const struct inode_operations ext2_dir_inode_operations;
extern const struct inode_operations ext2_special_inode_operations;

/* symlink.c */
extern const struct inode_operations ext2_fast_symlink_inode_operations;
extern const struct inode_operations ext2_symlink_inode_operations;

static inline ext2_fsblk_t
ext2_group_first_block_no(struct super_block *sb, unsigned long group_no)
{
        return group_no * (ext2_fsblk_t)EXT2_BLOCKS_PER_GROUP(sb) +
                le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block);
}
04-29
2008

看一段python的代码

IN:Python, 编程相关       Comments:1

def xselections(items, n):
    if n == 0:
        yield []
    else:
        for i in xrange(len(items)):
            for ss in xselections(items, n-1):
                yield [items[i]] + ss
for l in xselections(xrange(10), 3):
    print l

上面这段代码实现了从x数中取出y个数的全排列,xselections的实现用到了递归和yield,yield这个语句比较有意思:
“yield跟return一样会返回值,但是不一样的是return之后就退出函数了,而yield在丢出一次值给调用者之后还会返回继续运行生成器函数,并随着yield的再次调用丢出随后的生成值”

04-29
2008

Python-Challenge-2

IN:Python, 编程相关   Tags:    Comments:0

第五关:
不多说什么了,点点图片就可以发现了,直接贴代码上来:

#!/usr/bin/env python

from urllib import urlopen
import re

id = 12345

while id:
        url = "http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=%s" % id
        page = urlopen(url)
        text = page.read()
        print text
        id = ''.join(re.findall('and the next nothing is ([0-9].*)',text))
        print id

中间停了一下,出来个提示“Yes. Divide by two and keep going.”,刚开始还以为是分成两组,其实是除以2然后继续,那就手动把上面的id初始化为92118/2=46059。再运行一次程序就得到下一关的地址:peak.html。

第六关:
网页的源码中有一个提示“peak hell sounds familiar ”,我读了半天也没觉得熟悉,后来作了个弊,查了一下Python的函数,发现了pickle这个函数,peak,hell连读一下就是pickle了,这都可以。把网页改为pickle.html,会提示“yes! pickle!”,看来函数是找到了。然后在源代码中找到banner.p,获得这个文件里的内容,看起来乱七八糟的一些东西,其实就是使用pickle生成对象的一个序列,可以直接保存在文件里,关于pickle这里有一个简单的介绍,我也是现学的,贴代码:

#!/usr/bin/env python

import pickle
import sys

f = file('banner.p')
p = pickle.load(f)

print p
for a in p:
        for b in a:
                x,y = b
                while y:
                        sys.stdout.write(x)
                        y=y-1
        print
f.close()

从文件中会得到一个很长的list,仔细看看又是由好多个list组成,而这些list中数字之和都为95,根据banner.p这个文件名可以想到这是个字符图片,在上面的程序中我打印出了这个图片(有一点需要注意,你得把终端可显示的字符设置为至少95,不然会提前自动折行,这样就没办法看到这个banner了):
得到下一关地址:channel.html

04-24
2008

Python-Challenge-1

IN:Python, 编程相关   Tags:    Comments:3

第一关
其实第一次来这里时俺还不理解这个过关游戏,其实就是根据这一关网页上的一些提示来寻找下一关的URL;其中网页的标题往往是一些暗示。
由图可知:

#!/usr/bin/env python

print 2**38

计算出结果”274877906944“,然后修改URL为http://www.pythonchallenge.com/pc/def/274877906944.html,这就是第二关的地址,我们继续。

第二关
本来我想得是写程序对字母分别按照ascii值加2然后转换回字母,来查看网页上的那堆”乱码“,以下是比较”难看“的程序:

#!/usr/bin/env python

str = "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."

str1 = ""
for ch in str:
        if (ord(ch) >= ord('a')) and (ord(ch) < = ord('z')):
                str1+=chr((ord(ch)+2-ord('a'))%26+ord('a'))
        else:
                str1+=ch
print str1

看到翻译出来的话后俺才知道有个东西叫做maketrans,再看看使用maketrans写的代码吧:

#!/usr/bin/env python

import string

str = "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."

print string.translate(str,string.maketrans('abcdefghijklmnopqrstuvwxyz','cdefghijklmnopqrstuvwxyzab'))

现在根据提示在URL中进行这个转换,map.html改为orc.html就好了。

第三关:
根据上面的提示,在网页的源代码中找到一堆字符,源代码中有提示”find rare characters in the mess below“,开始写程序提取出这堆字符中的字母:

#!/usr/bin/env python

import re
import string

def find_char():
        list = []
        f = file('mess.txt')
        p = re.compile('[a-z]')
        for l in f.readlines():
                char = p.findall(l)
                if char != []: list.extend(char)
        print ''.join(list)
        f.close()
find_char()

这里使用了正则表达式来判断字母,那一堆的字符我保存在了mess.txt文件中。运行程序后得到”equality”,把orc.html改为equality.html,得到下一关地址。

第四关:
上面有提示”One small letter, surrounded by EXACTLY three big bodyguards on each of its sides.“,虽然人家在上面对单词”EXACTLY“加粗了,我还是开始没注意到含义是”只有“三个大写字母,写正则表达式时匹配到了一堆东西,后来才想起是”有且只有“三个大写字母,看代码:

#!/usr/bin/env python

import re
import string

def find_foo():
        list = []
        f = file('mess1.txt')
        p = re.compile('[^A-Z][A-Z]{3}([a-z])[A-Z]{3}[^A-Z]')
        for l in f.readlines():
                char = p.findall(l)
                if char != []: list.extend(char)
        print ''.join(list)
        f.close()
find_foo()

运行后会得到linkedlist,得到下一关的地址:-)

04-23
2008
Page 10 of 22« First...8910111220...Last »
loading...