RCR 222: Add bitwise AND/XOR/OR/NOT for String
submitted by David Garamond on Thu Feb 26 2004 01:38:26 AM -0800
Status: pending
Abstract
Add String#^, #!, #&, and #~ for fast bitwise operations on byte strings.
Problem
Unlike in Perl, there is currently no fast way in Ruby to do bitwise operations on byte strings. The bitwise-op methods #^, #!, #&, and #~ works only on numbers and not string.
Proposal
Implement String#^, #!, #&, and #~ in C.
Analysis
I think this is a low-impact change and mainly affect performance, because Ruby's String is a raw/byte string (not Unicode, etc). C implementation should be simple and straightforward. A couple of additional issues to consider though: 1) we can allow strings of different length to be XOR/AND/OR-ed. If the second string is shorter than the first, then we can just reuse/rollover to the beginning of the second string; 2) Ara T. Howard in ruby-talk suggested adding String#and!, #xor!, #not!, #or! too for in-place replacement.
Implementation
class String
def ^(other)
raise ArgumentError, "Can't bitwise-XOR a String with a non-String" \
unless other.kind_of? String
raise ArgumentError, "Can't bitwise-XOR strings of different length" \
unless self.length == other.length
result = (0..self.length-1).collect { |i| self[i] ^ other[i] }
result.pack("C*")
end
def &(other)
raise ArgumentError, "Can't bitwise-AND a String with a non-String" \
unless other.kind_of? String
raise ArgumentError, "Can't bitwise-AND strings of different length" \
unless self.length == other.length
result = (0..self.length-1).collect { |i| self[i] & other[i] }
result.pack("C*")
end
def |(other)
raise ArgumentError, "Can't bitwise-OR a String with a non-String" \
unless other.kind_of? String
raise ArgumentError, "Can't bitwise-OR strings of different length" \
unless self.length == other.length
result = (0..self.length-1).collect { |i| self[i] | other[i] }
result.pack("C*")
end
def ~
result = (0..self.length-1).collect { |i| ~ self[i] }
result.pack("C*")
end
end
Vote for this RCR
two points:
- how often do we need bit-wise string operation?
- strings in Ruby2 will no longer be raw byte string. how can we define bit-wise operation on those?
-- matz.
Maybe it would be possible to have some sort of BitVector class that has these operations as part of the standard library for Ruby2? I'm also thinking that we should have a ByteString class because some uses of Ruby Strings take advantage of the fact that they are simply binary arrays (such as storing FXRuby icons as resource strings). -- Austin Ziegler
Thanks for the comments, matz. Since Ruby2 will have separate String and ByteString class, I still think we should add a pretty complete set of methods for ByteString, including bitwise operations. I don't know exactly how often we will use bitwise, but I think there will be uses in file processing, cryptography, and image processing. -- davegaramond
There is a library that I'm looking at implementing in Ruby that this would help with immensely (magic file detection, similar to libmmagic). -- Austin Ziegler
Back to RCRchive.
RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog