Как выполнить поиск в двоичном файле и заменить строку на Ruby?

#ruby #windows #security #replace

#ruby #Windows #Безопасность #заменить

Вопрос:

Новичок в Ruby здесь. Я использую Ruby версии 1.9.2. Я работаю на военном объекте, и всякий раз, когда требуется отправить данные поддержки нашим поставщикам, их необходимо очистить от информации об идентификаторе IP и имени хоста. Это новая роль для меня, и теперь задача очистки файлов (как текстовых, так и двоичных) ложится на меня при решении вопросов поддержки.

Я создал следующий скрипт для «очистки» файлов от простых текстовых файлов с информацией об IP-адресе:

 File.open("subnet.htm", 'r ') do |f|
  text = f.read
  text.gsub!(/d{1,3}.d{1,3}.d{1,3}.d{1,3}/, "000.000.000.000")
  f.rewind
  f.write(text)
end
  

Мне нужно изменить свой скрипт для поиска и замены информации об имени хоста и IP-адресе в текстовых файлах и двоичных файлах .dat. Я ищу что-то действительно простое, например, мой маленький скрипт выше, и я бы хотел сохранить обработку файлов txt и dat в виде отдельных скриптов. Я хотел бы рассмотреть задачу создания одного скрипта для выполнения обоих действий в качестве учебного упражнения из двух отдельных скриптов. Прямо сейчас у меня есть определенные временные ограничения, чтобы очистить файлы поддержки и отправить их.

Приоритетом для меня является очистка моих файлов трассировки binary .dat, которые имеют тип данных XML. Это двоичные файлы трассировки производительности из наших массивов хранения, и перед отправкой в службу поддержки для анализа необходимо удалить идентифицирующую информацию об IP-адресе.

Я искал stackoverflow.com несколько обширно и не нашел вопроса с ответом, который отвечал бы моим конкретным потребностям, и я просто потратил время, пытаясь разобраться в string.unpack.

Спасибо.

Комментарии:

1. Я не понимаю, что вы подразумеваете под «двоичными» XML-файлами? xml-файлы обычно представляют собой текстовые файлы.

2. Обратите внимание, что а) вы могли бы сделать свое регулярное выражение IP немного более жестким (например 999.999.999.999 , это недопустимый IP-адрес, но он будет сопоставлен, и то, что у вас есть, также будет соответствовать части 1.2.3.4.5.6.7 ) , но, что более важно, б) вы предполагаете только адреса IPv4, а не IPv6.

3. ennuikiller, да, согласен. Эти двоичные файлы перечислены в виде xml ‘types’, но явно являются двоичными и нечитаемыми в текстовом редакторе, что было странным и запутанным. Phrogz, спасибо. И это адресовано только IP4, потому что IP4 — это единственные адреса, с которыми я работаю в настоящее время.

Ответ №1:

В общем случае Ruby обрабатывает двоичные файлы так же, как и другие файлы, с двумя оговорками:

  1. В Windows чтение файлов обычно переводит пары CRLF только в LF. Вам нужно читать в двоичном режиме, чтобы гарантировать отсутствие преобразования:

     File.open('foo.bin','rb'){ ... }
      
  2. Чтобы убедиться, что ваши двоичные данные не интерпретируются как текст в какой-либо другой кодировке в Ruby 1.9 , вам необходимо указать кодировку ASCII-8BIT:

     File.open('foo.bin','r:ASCII-8BIT'){ ... }
      

    Однако, как отмечалось в этом сообщении, установка флага ‘b’, как показано выше, также устанавливает кодировку для вас. Таким образом, просто используйте первый фрагмент кода выше.

Однако, как отмечено в комментарии @ennuikiller, я подозреваю, что на самом деле у вас нет истинных двоичных данных. Если вы действительно читаете текстовые файлы с кодировкой, отличной от ASCII (например, UTF-8), существует небольшая вероятность того, что обработка их как двоичных файлов случайно обнаружит только половину многобайтовой кодировки и нанесет ущерб результирующему файлу.

Редактировать: Чтобы использовать Nokogiri для файлов XML, вы можете сделать что-то вроде следующего:

 require 'nokogiri'
File.open("foo.xml", 'r ') do |f|
  doc = Nokogiri.XML(f.read)
  doc.xpath('//text()').each do |text_node|
    # You cannot use gsub! here
    text_node.content = text_node.content.gsub /.../, '...'
  end
  f.rewind
  f.write doc.to_xml
end
  

Ответ №2:

Я провел некоторый синтаксический анализ двоичного файла, и вот как я его прочитал и очистил:

 data = File.open("file", 'rb' ) {|io| io.read}.unpack("C*").map do |val| 
  val if val == 9 || val == 10 || val == 13 || (val > 31 amp;amp; val < 127) 
end
  

Для меня в моем двоичном файле не было последовательных символьных строк, поэтому мне пришлось выполнить некоторое смещение и фильтрацию, прежде чем я смог его прочитать (отсюда .map do |val| ... end и распаковка с "C" тегом (см. http://www.ruby-doc.org/core-1.9.2/String.html#method-i-unpack ) будет выдавать коды символов ASCII, а не буквы, поэтому позвоните val.chr , если вы хотите использовать интерпретируемый символ вместо этого.

Я бы посоветовал вам открыть свои файлы в двоичном редакторе и просмотреть их, чтобы определить, как наилучшим образом обрабатывать синтаксический анализ данных. Если они представляют собой XML, вы можете рассмотреть возможность их синтаксического анализа с помощью Nokogiri или аналогичного XML-инструмента.

Комментарии:

1. Эта середина — катастрофа, которую можно устранить простым case утверждением: when 9, 10, 13, 32..126

2. @tadman согласился… Это было примерно в первый месяц моего программирования на ruby, и список задач еще не вернулся к «очистке вашего старого кода». Спасибо.