Skip to content

Instantly share code, notes, and snippets.

@movitto
Created February 6, 2019 14:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save movitto/bc5902caded1979fa55be2b18a6d78e3 to your computer and use it in GitHub Desktop.
Save movitto/bc5902caded1979fa55be2b18a6d78e3 to your computer and use it in GitHub Desktop.
Determine XRP account entropy by character and substring occurances in Base58 representation
#!/usr/bin/ruby
# Determine XRP account entropy, takes in a list of XRP accounts and
# outputs distribution by length, character, positional character,
# substring, and case-insensitive substring
require 'workers'
# Add method to extract all String substrings of a given length
class String
def substrings(n)
(0..size-n).map{|x| self[x..x+n-1] }
end
end
# Read in accounts, populate queue
accounts = Queue.new
File.read("accounts.org")
.split("\n")
.each { |f|
accounts << f
}
# Output data
by_len = {}
by_char = {}
by_char_for_pos = Array.new(34) { Hash.new }
substrings = {}
isubstrings = {}
# Setup worker to monitor progress
work = Workers::TaskGroup.new
work.add do
l = accounts.size
until accounts.empty?
puts "#{accounts.size}: #{l-accounts.size}"
l = accounts.size
sleep 3
end
end
# Crunch data
10.times do
work.add do
until accounts.empty?
a = nil
begin
a = accounts.pop(true)
rescue
next
end
by_len[a.size] ||= 0
by_len[a.size] += 1
# slice off the leading 'r'
a = a[1..-1]
a.chars.each_with_index { |c, ci|
by_char[c] ||= 0
by_char[c] += 1
by_char_for_pos[ci][c] ||= 0
by_char_for_pos[ci][c] += 1
}
[3,5,7].each { |s|
substrings[s] ||= {}
isubstrings[s] ||= {}
a.substrings(s).each { |substr|
substrings[s][substr] ||= 0
substrings[s][substr] += 1
downcase = substr.downcase
isubstrings[s][downcase] ||= 0
isubstrings[s][downcase] += 1
}
}
end
end
end
work.run
# Write output
File.write "output/len", by_len.collect { |l,n|
"#{l},#{n}"
}.join("\n")
File.write "output/char", by_char.collect { |c,n|
"#{c},#{n}"
}.join("\n")
File.write "output/pos_char", by_char_for_pos.collect { |by_char|
by_char.collect { |c,n|
"#{c} #{n}"
}.join(",")
}.join("\n")
substrings.keys.each { |l|
sl = substrings[l].sort_by { |k,v| v }.reverse.to_h
File.write "output/substrings#{l}", sl.collect { |s, n|
"#{s},#{n}"
}.join("\n")
}
isubstrings.keys.each { |l|
isl = isubstrings[l].sort_by { |k,v| v }.reverse.to_h
File.write "output/isubstrings#{l}", isl.collect { |s, n|
"#{s},#{n}"
}.join("\n")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment