我正在构建一个工具来帮助我对数据库文件进行反向工程。我将我的工具定位到固定记录长度的平面文件。
我所知道的: 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
答案 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
利用记录大小不变的事实。取每个可能的分隔符并检查每条记录与通常记录长度的偏差。如果标题比文件的其余部分足够小,则应该可以正常工作。