Created
February 6, 2019 14:54
-
-
Save movitto/bc5902caded1979fa55be2b18a6d78e3 to your computer and use it in GitHub Desktop.
Determine XRP account entropy by character and substring occurances in Base58 representation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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