Create a little more structure around the tools - warvox - VoIP based wardialing tool, forked from rapid7/warvox.
DIR Log
DIR Files
DIR Refs
DIR README
---
DIR commit 60be9accc104b2d63ff2ab74bf586b4ce054a524
DIR parent 18b3b7c1dbb56be8aed57018765ebad24655d98b
HTML Author: HD Moore <hd_moore@rapid7.com>
Date: Fri, 13 Feb 2009 06:23:40 +0000
Create a little more structure around the tools
Diffstat:
M bin/create_flow.rb | 91 ++-----------------------------
A bin/create_flowdb.rb | 40 +++++++++++++++++++++++++++++++
M bin/create_samples.rb | 15 ++++++---------
M bin/create_sig.rb | 84 ++++---------------------------
A data/test.db.bz2 | 0
M lib/warvox.rb | 5 +++--
A lib/warvox/audio.rb | 2 ++
A lib/warvox/audio/error.rb | 7 +++++++
A lib/warvox/audio/raw.rb | 129 +++++++++++++++++++++++++++++++
A lib/warvox/db.rb | 113 +++++++++++++++++++++++++++++++
10 files changed, 316 insertions(+), 170 deletions(-)
---
DIR diff --git a/bin/create_flow.rb b/bin/create_flow.rb
@@ -13,93 +13,12 @@ require 'warvox'
#
# Script
-#
-
-#
-# Parameters
-#
-lo_lim = 100
-lo_min = 5
-lo_cnt = 0
-hi_min = 5
-hi_cnt = 0
-
-#
-# Input
#
-cnt = 0
-inp = ARGV.shift || exit
-raw = File.read(inp)
-data = raw.unpack("s*").map {|c| c.abs}
-
-#
-# Granular hi/low state change list
-#
-fprint = []
-state = :lo
-idx = 0
-buff = []
-
-while (idx < data.length)
- case state
- when :lo
- while(idx < data.length and data[idx] <= lo_lim)
- buff << data[idx]
- idx += 1
- end
-
- # Ignore any sequence that is too small
- fprint << [:lo, buff.length, buff - [0]] if buff.length > lo_min
- state = :hi
- buff = []
- next
- when :hi
- while(idx < data.length and data[idx] > lo_lim)
- buff << data[idx]
- idx += 1
- end
-
- # Ignore any sequence that is too small
- fprint << [:hi, buff.length, buff] if buff.length > hi_min
- state = :lo
- buff = []
- next
- end
-end
-
-
-#
-# Merge similar blocks
-#
-final = []
-prev = fprint[0]
-idx = 1
-
-while(idx < fprint.length)
-
- if(fprint[idx][0] == prev[0])
- prev[1] += fprint[idx][1]
- prev[2] += fprint[idx][2]
- else
- final << prev
- prev = fprint[idx]
- end
-
- idx += 1
-end
-final << prev
-
-
-#
-# Process results
-#
-sig = "#{inp} "
-final.each do |f|
- sum = 0
- f[2].each {|i| sum += i }
- avg = (sum == 0) ? 0 : sum / f[2].length
- sig << "#{f[0].to_s.upcase[0,1]},#{f[1]},#{avg} "
+def usage
+ $stderr.puts "#{$0} [audio.raw]"
+ exit
end
-puts sig
+raw = WarVOX::Audio::Raw.from_file(ARGV.shift || usage)
+puts raw.to_flow
DIR diff --git a/bin/create_flowdb.rb b/bin/create_flowdb.rb
@@ -0,0 +1,40 @@
+#!/usr/bin/env ruby
+###################
+
+#
+# Load the library path
+#
+base = __FILE__
+while File.symlink?(base)
+ base = File.expand_path(File.readlink(base), File.dirname(base))
+end
+$:.unshift(File.join(File.expand_path(File.dirname(base)), '..', 'lib'))
+require 'warvox'
+
+#
+# Script
+#
+
+def usage
+ $stderr.puts "#{$0} [/path/to/audio/] [output.db]"
+ exit
+end
+
+src = ARGV.shift || usage
+dst = ARGV.shift || usage
+db = File.new(dst, "w")
+dir = Dir.new(src)
+cnt = 0
+
+set = dir.entries.sort.grep(/\.raw$/)
+set.each do |ent|
+ next if not ent =~ /\.raw$/
+ puts "[*] [#{sprintf("%.5d/%.5d", cnt+1, set.length)}] Processing #{ent}..."
+ raw = WarVOX::Audio::Raw.from_file( File.join(src, ent) )
+ db.write( ent.gsub('.raw', '') + " " + raw.to_flow + "\n" )
+ cnt += 1
+end
+
+db.close
+
+puts "[*] Wrote #{cnt} database entries into #{dst}"
DIR diff --git a/bin/create_samples.rb b/bin/create_samples.rb
@@ -15,17 +15,14 @@ require 'warvox'
# Script
#
-=begin
- 8,000 samples per second
- 160 samples per block of data
-=end
+def usage
+ $stderr.puts "#{$0} [audio.raw]"
+ exit
+end
cnt = 0
-inp = ARGV.shift || exit
-raw = File.read(inp)
-raw.unpack("v*").each do |s|
- val = (s > 0x7fff) ? (0x10000 - s) * -1 : s
+raw = WarVOX::Audio::Raw.from_file(ARGV.shift || usage)
+raw.samples.each do |val|
puts "#{cnt} #{val}"
cnt += 1
end
-
DIR diff --git a/bin/create_sig.rb b/bin/create_sig.rb
@@ -15,81 +15,19 @@ require 'warvox'
# Script
#
-inp = ARGV.shift()
-num1 = ARGV.shift() || exit
-num2 = ARGV.shift() || exit
-
-min_len = 800
-
-
-info1 = []
-info2 = []
-
-fd = File.open(inp, "r")
-fd.each_line do |line|
- data = line.strip.split(/\s+/)
- name = data.shift
- next if name !~ /#{num1}|#{num2}/
-
- # Bump the leading silence off
- data.shift if data[0] =~ /^L/
-
- data.each do |d|
- s,l,a = d.split(",")
- next if l.to_i < min_len
- plot = [s, l.to_i, a.to_i]
- name =~ /#{num1}/ ? info1 << plot : info2 << plot
- end
-
- break if (info1.length > 0 and info2.length > 0)
-end
-
-if (not (info1.length > 0 and info2.length > 0))
- $stderr.puts "error: could not find both numbers in the database"
+def usage
+ $stderr.puts "#{$0} [warvox.db] [num1] [num2] <fuzz-factor> <db-threshold>"
exit
end
+inp = ARGV.shift() || usage
+num1 = ARGV.shift() || usage
+num2 = ARGV.shift() || usage
+fuzz = (ARGV.shift() || 100).to_i
+thresh = (ARGV.shift() || 800).to_i
-min_sig = 2
-fuzz = 100
-idx = 0
-fnd = nil
-r = 0
-
-while(idx < info1.length-min_sig)
- sig = info1[idx,info1.length]
- idx2 = 0
-
- while (idx2 < info2.length)
- c = 0
- 0.upto(sig.length-1) do |si|
- break if not info2[idx2+si]
- break if not (
- sig[si][0] == info2[idx2+si][0] and
- info2[idx2 + si][1] > sig[si][1]-fuzz and
- info2[idx2 + si][1] < sig[si][1]+fuzz
- )
- c += 1
- end
-
- if (c > r)
- r = c
- fnd = sig[0, r]
- end
- idx2 += 1
- end
- idx += 1
-end
-
-
-
-
-version = "1.0"
+info1 = []
+info2 = []
-if(fnd)
- sig = "V=#{version},F=#{fuzz},S1=#{num1},S2=#{num2},L=#{r} "
- fnd.each do |i|
- sig << i.join(",") + " "
- end
- puts sig
-end
+wdb = WarVOX::DB.new(inp, thresh)
+puts wdb.find_sig(num1, num2, { :fuzz => fuzz }).inspect
DIR diff --git a/data/test.db.bz2 b/data/test.db.bz2
Binary files differ.
DIR diff --git a/lib/warvox.rb b/lib/warvox.rb
@@ -3,6 +3,7 @@
##
module WarVOX
-
-
end
+
+require 'warvox/audio'
+require 'warvox/db'
DIR diff --git a/lib/warvox/audio.rb b/lib/warvox/audio.rb
@@ -0,0 +1,2 @@
+require 'warvox/audio/error'
+require 'warvox/audio/raw'
DIR diff --git a/lib/warvox/audio/error.rb b/lib/warvox/audio/error.rb
@@ -0,0 +1,7 @@
+module WarVOX
+module Audio
+class Error < ::RuntimeError
+
+end
+end
+end
DIR diff --git a/lib/warvox/audio/raw.rb b/lib/warvox/audio/raw.rb
@@ -0,0 +1,129 @@
+module WarVOX
+module Audio
+class Raw
+
+ ##
+ # RAW AUDIO - 8khz little-endian 16-bit signed
+ ##
+
+ ##
+ # Static methods
+ ##
+
+ def self.from_str(str)
+ self.class.new(str)
+ end
+
+ def self.from_file(path)
+ if(not path)
+ raise Error, "No audio path specified"
+ end
+
+ if(path == "-")
+ return self.new($stdin.read)
+ end
+
+ if(not File.readable?(path))
+ raise Error, "The specified audio file does not exist"
+ end
+
+ self.new(File.read(path, File.size(path)))
+ end
+
+ ##
+ # Class methods
+ ##
+
+ attr_accessor :samples
+
+ def initialize(data)
+ self.samples = data.unpack('v*').map do |s|
+ (s > 0x7fff) ? (0x10000 - s) * -1 : s
+ end
+ end
+
+ def to_flow(opts={})
+
+ lo_lim = (opts[:lo_lim] || 100).to_i
+ lo_min = (opts[:lo_min] || 5).to_i
+ hi_min = (opts[:hi_min] || 5).to_i
+ lo_cnt = 0
+ hi_cnt = 0
+
+ data = self.samples.map {|c| c.abs}
+
+ #
+ # Granular hi/low state change list
+ #
+ fprint = []
+ state = :lo
+ idx = 0
+ buff = []
+
+ while (idx < data.length)
+ case state
+ when :lo
+ while(idx < data.length and data[idx] <= lo_lim)
+ buff << data[idx]
+ idx += 1
+ end
+
+ # Ignore any sequence that is too small
+ fprint << [:lo, buff.length, buff - [0]] if buff.length > lo_min
+ state = :hi
+ buff = []
+ next
+ when :hi
+ while(idx < data.length and data[idx] > lo_lim)
+ buff << data[idx]
+ idx += 1
+ end
+
+ # Ignore any sequence that is too small
+ fprint << [:hi, buff.length, buff] if buff.length > hi_min
+ state = :lo
+ buff = []
+ next
+ end
+ end
+
+ #
+ # Merge similar blocks
+ #
+ final = []
+ prev = fprint[0]
+ idx = 1
+
+ while(idx < fprint.length)
+
+ if(fprint[idx][0] == prev[0])
+ prev[1] += fprint[idx][1]
+ prev[2] += fprint[idx][2]
+ else
+ final << prev
+ prev = fprint[idx]
+ end
+
+ idx += 1
+ end
+ final << prev
+
+ #
+ # Process results
+ #
+ sig = ""
+
+ final.each do |f|
+ sum = 0
+ f[2].each {|i| sum += i }
+ avg = (sum == 0) ? 0 : sum / f[2].length
+ sig << "#{f[0].to_s.upcase[0,1]},#{f[1]},#{avg} "
+ end
+
+ # Return the results
+ return sig
+ end
+
+end
+end
+end
DIR diff --git a/lib/warvox/db.rb b/lib/warvox/db.rb
@@ -0,0 +1,113 @@
+module WarVOX
+class DB
+
+ VERSION = '1.0'
+
+ class Error < ::RuntimeError
+ end
+
+ attr_accessor :path, :nums, :threshold, :version
+
+ def initialize(path, threshold=800)
+ self.path = path
+ self.threshold = threshold
+ self.nums = {}
+ self.version = VERSION
+
+ File.open(path, "r") do |fd|
+ fd.each_line do |line|
+ line.strip!
+ next if line.empty?
+ bits = line.split(/\s+/)
+ name = bits.shift
+
+ self.nums[name] = []
+ bits.each do |d|
+ s,l,a = d.split(',')
+ next if l.to_i < self.threshold
+ self.nums[name] << [s, l.to_i, a.to_i]
+ end
+ end
+ end
+ end
+
+ def [](num)
+ self.nums[num]
+ end
+
+ def []=(num,val)
+ self.nums[num] = val
+ end
+
+ #
+ # Utility methods
+ #
+
+ def find_sig(num1, num2, opts={})
+
+ fuzz = opts[:fuzz] || 100
+ info1 = self[num1]
+ info2 = self[num2]
+
+ # Make sure both samples exist in the database
+ if ( not (info1 and info2 and not (info1.empty? or info2.empty?) ) )
+ raise Error, "The database must contain both numbers"
+ end
+
+ min_sig = 2
+ idx = 0
+ fnd = nil
+ mat = nil
+ r = 0
+
+ while(idx < info1.length-min_sig)
+ sig = info1[idx,info1.length]
+ idx2 = 0
+
+ while (idx2 < info2.length)
+ c = 0
+ 0.upto(sig.length-1) do |si|
+ break if not info2[idx2+si]
+ break if not (
+ sig[si][0] == info2[idx2+si][0] and
+ info2[idx2 + si][1] > sig[si][1]-fuzz and
+ info2[idx2 + si][1] < sig[si][1]+fuzz
+ )
+ c += 1
+ end
+
+ if (c > r)
+ r = c
+ fnd = sig[0, r]
+ mat = info2[idx2, r]
+ end
+ idx2 += 1
+ end
+ idx += 1
+ end
+
+ return nil if not fnd
+
+ sig = []
+ fnd.each_index do |i|
+ sig <<
+ [
+ (fnd[i][0]),
+ (fnd[i][1] + mat[i][1] / 2.0).to_i,
+ (fnd[i][2] + mat[i][2] / 2.0).to_i
+ ]
+ end
+
+ {
+ :version => self.version,
+ :fuzz => fuzz,
+ :threshold => self.threshold,
+ :num1 => num1,
+ :num2 => num2,
+ :len => r,
+ :sig => sig
+ }
+ end
+
+end
+end