# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+require 'narray'
+
# Error class for all exceptions to do with String.
class StringError < StandardError; end
# Monkey patching Class String to add bitwise operators.
-# Behaviour matching Perl's:
-# http://perldoc.perl.org/perlop.html#Bitwise-String-Operators
class String
# Method to that returns the case senstive Hamming Distance between two strings.
# http://en.wikipedia.org/wiki/Hamming_distance
- def self.hamming_dist(str1, str2)
- raise StringError, "Uneven string lengths: #{str1.length} != #{str2.length}" if str1.length != str2.length
- (str1 ^ str2 ).count("\x01-\xff")
+ def hamming_distance(str)
+ (self ^ str).tr("\x00",'').length
end
# Method that performs bitwise AND operation where bits
- # are copied if they exists in BOTH operands. If the operand
- # sizes are different, the & operator methods acts as though
- # the longer operand were truncated to the length of the shorter.
+ # are copied if they exists in BOTH operands.
def &(str)
- new = ""
-
- (0 ... [self.length, str.length].min).each do |i|
- new << (self[i].ord & str[i].ord)
- end
+ narray1, narray2 = to_narray(self, str)
- new
+ (narray1 & narray2).to_s
end
# Method that performs bitwise OR operation where bits
- # are copied if they exists in EITHER operands. If the operand
- # sizes differ, the shorter operand is extended with the terminal
- # part of the longer operand.
+ # are copied if they exists in EITHER operands.
def |(str)
- new = ""
-
- min = [self.length, str.length].min
-
- (0 ... min).each do |i|
- new << (self[i].ord | str[i].ord)
- end
+ narray1, narray2 = to_narray(self, str)
- if self.length > str.length
- new << self[min ... self.length]
- elsif self.length < str.length
- new << str[min ... str.length]
- end
-
- new
+ (narray1 | narray2).to_s
end
# Method that performs bitwise XOR operation where bits
# are copied if they exists in ONE BUT NOT BOTH operands.
def ^(str)
- new = ""
+ narray1, narray2 = to_narray(self, str)
+
+ (narray1 ^ narray2).to_s
+ end
+
+ private
- (0 ... [self.length, str.length].min).each do |i|
- new << (self[i].ord ^ str[i].ord)
+ def to_narray(str1, str2)
+ if str1.length != str2.length
+ raise StringError, "Uneven string lengths: #{str1.length} != #{str2.length}"
end
- new
+ narray1 = NArray.to_na(str1, "byte")
+ narray2 = NArray.to_na(str2, "byte")
+
+ [narray1, narray2]
end
end