• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ruby写的BT种子解析器

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

class MyFile < File
  
def peek(len)
    str 
= self.read(len)
    self.pos 
-= len
    str
  end  
end

#字段信息
class TVal
  attr_accessor :Type
  attr_accessor :Value
  
  
def to_s()
    @Value
  end
  
end

#文件信息
class TFile
  attr_reader :Length
  attr_reader :Path
  attr_reader :Name
  attr_reader :FirstPiece
  attr_reader :PieceLength
  
  
def initialize(size, fullPath, pStart, pLen)
    @Length 
= Size
    @FirstPiece 
= pStart
    @PieceLength 
= pLen
    fileNamePos 
= fullPath.rindex('\\')
    
if fileNamePos.nil? then
      @Path 
= ""
      @Name 
= fullPath
    
else
      @Path 
= fullPath[0..fileNamePos]
      @Name 
= fullPath[fileNamePos..fullPath.length-1]
    end
  end
end
  

class TorrentParser
  attr_accessor :Root
  
def initialize(tPath)
    
    @Path 
= tPath
    @Size 
= nil
    
    @Root 
= nil
    @Files 
= nil
    
    @Torrent 
= nil
    @TotalValues 
= 0
    
    @InfoStart 
= nil
    @InfoEnd 
= nil
    
  end
  
#主函数
  def Process()
    
raise "File doesn't exist"  if !MyFile.exist? @Path #检测文件路径
    @TotalValues = 0
    
    @Torrent 
= MyFile.new @Path
    @Torrent.binmode

    
raise "Torrent File Error" if @Torrent.read(1!= 'd'
    
    @Root 
= ProcessDict()
    @Files 
= GetFiles()
    
  end
  
#读取一个字典
  def ProcessDict()
    tempDict 
= Hash.new

    
while @Torrent.peek(1!= 'e' #向后读一个字符 看看是不是e 如果是e的话 说明dictionary结束了
      key = ProcessString() #读取一个Key Name

      
if key == 'info' then #如果是名字为info的key
        @InfoStart = @Torrent.pos #设置info start的index
      end
      
if key == 'pieces' then #如果是pieces的key 则按照特殊的byte方式读取
        val = TVal.new
        val.Type 
= "BYTE"
        val.Value 
= ProcessByte()
        tempDict[key] 
= val
      
else
        val 
= ProcessVal() #否则读该key的Val
        tempDict[key] = val
      end
      
if key == "info" then
        @InfoEnd 
= @Torrent.pos - @InfoStart
      end
    end
    @Torrent.read 
1 #读掉结尾的"e"
    
    
return tempDict
  end
  
  

  
#读取一个字串
  def ProcessString()
    tempLen 
= ''
    tempLen 
+= @Torrent.read(1while @Torrent.peek(1!= ':' #获取字串长度
    
    @Torrent.read(
1# 将后面的冒号读掉    

    content 
= @Torrent.read(tempLen.to_i) #然后读指定长度的字符串 并返回 

    
return content
  end
    

  
#读取字节串
  def ProcessByte()
    tempLen 
= ''
    tempLen 
+= @Torrent.read(1while @Torrent.peek(1!= ':' #获取字串长度
    
    @Torrent.read(
1# 将后面的冒号读掉    
    
    chrs 
= Array.new
    (
1..tempLen.to_i).each{|idx|
      byte 
= @Torrent.readchar
      chrs 
<< "%02X" % byte
    }
    chrs
  end
  

  
#读一个数字
  def ProcessInt()
    tempInt 
= ''
    tempInt 
+= @Torrent.read(1while @Torrent.peek(1!= 'e'

    @Torrent.read(
1#把最后的e读掉
    tempInt.to_i
  end
  
#读一个列表
  def ProcessList()
    tempList 
= Array.new
    
while @Torrent.peek(1!= 'e'
      tempList 
<< ProcessVal
    end
    tempList
  end
    
  
#读取一个Val
  def ProcessVal()
    @TotalValues 
+= 1
    
    val 
= TVal.new
    
    
    case @Torrent.peek(
1)
      when 
'd'
        @Torrent.read(
1)  #把d读掉
        val.Type = "DICT"
        val.Value 
= ProcessDict()
      when 
'l'
        @Torrent.read(
1#把l读掉
        val.Type = "LIST" 
        val.Value 
= ProcessList()
      when 
'i'
        @Torrent.read(
1#把i读掉
        val.Type = "INT"
        val.Value 
= ProcessInt()
      
else
        val.Type 
= "STRING"
        val.Value 
= ProcessString()
    end
    val
  end
  
end

begin
  _torrent 
= TorrentParser.new ARGV.shift
  _torrent.Process
  
  _torrent.Root.map{
|key,value|
    case value.Type
      when 
'LIST'
        puts 
"#{key}(#{value.Type})\t\t#{value.Value}"
      when 
'BYTE'
        puts 
"#{key}(#{value.Type})\t\t%0X", value.Value
      when 
'DICT'
        value.Value.map{
|skey,svalue|
          puts 
"--#{skey}(#{svalue.Type})\t\t#{svalue.Value}"
        }
      
else
        puts 
"#{key}(#{value.Type})\t\t#{value.Value}"
    end
  }
  
rescue
  puts $!
  puts $@
end

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Mac OS X 安装ruby环境发布时间:2022-07-13
下一篇:
最近又开始搞rubyonrails了发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap