如何在字节数组中找到未知模式?

时间:2015-11-02 21:45:00

标签: ruby database reverse-engineering

我正在构建一个工具来帮助我对数据库文件进行反向工程。我将我的工具定位到固定记录长度的平面文件。

我所知道的:   1)每条记录都有一个索引(ID)。   2)每个记录由分隔符分隔。   3)每条记录都是固定宽度。   4)每个记录中的每列至少相隔一个x00字节。   5)文件头在开头(我说这是因为标题不包含分隔符..)

我在其他文件中找到的分隔符是:(xFAxFA,xFExFE,xFDxFD)但考虑到我将来可能在不同的数据库上使用该工具,这是无关紧要的。所以我需要一些能够挑选出“模式”的东西。尽管它是由多少字节组成的。可能不超过6个字节?如果它更多,它可能会吃掉过多的数据。但是,我这样做的经验是有限的。

所以我猜我的问题是,如何在大文件中找到UNKNOWN分隔符?我觉得,给我,我所知道的'我应该能够编程,我只是不知道从哪里开始...

 # Really loose pseudo code
 def begin_some_how
   # THIS IS THE PART I NEED HELP WITH...
   # find all non-zero non-ascii sets of 2 or more bytes that repeat more than twice.
 end

 def check_possible_record_lengths
   possible_delimiter = begin_some_how
   # test if any of the above are always the same number of bytes apart from each other(except one instance, the header...)
   possible_records = file.split(possible_delimiter)
   rec_length_count = possible_records.map{ |record| record.length}.uniq.count
   if rec_length_count == 2 # The header will most likely not be the same size.
     puts "Success! We found the fixed record delimiter: #{possible_delimiter}
   else
     puts "Wrong delimiter found"
   end
 end

1 个答案:

答案 0 :(得分:0)

possible = [",", "."]

result = [0, ""]
possible.each do |delimiter|
    sizes = file.split( delimiter ).map{ |record| record.size }
    next if sizes.size < 2

    average = 0.0 + sizes.inject{|sum,x| sum + x }  
    average /= sizes.size    #This should be the record length if this is the right delimiter

    deviation = 0.0 + sizes.inject{|sum,x| sum + (x-average)**2 }

    matching_value = average / (deviation**2)
    if matching_value > result[0] then
        result[0] = matching_value
        result[1] = delimiter
    end

end

利用记录大小不变的事实。取每个可能的分隔符并检查每条记录与通常记录长度的偏差。如果标题比文件的其余部分足够小,则应该可以正常工作。