# Logical Operations on Strings

**URL:** <https://www.ruby-forum.com/t/logical-operations-on-strings/127325>\
**Category:** Ruby\
**Created:** [January 28, 2008, 9:21am UTC](https://www.ruby-forum.com/t/logical-operations-on-strings/127325 "2008-01-28T09:21:24Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michael\_WSRyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/53a042/32.png) [@Michael\_WSRyder](https://www.ruby-forum.com/u/Michael_WSRyder)\
**Post date:** [January 28, 2008, 9:21am UTC](https://www.ruby-forum.com/t/logical-operations-on-strings/127325/1 "2008-01-28T09:21:24Z")

</div>

Is there a bitwise and for strings that I am missing? I tried the  
documentation and Google with no luck. I coded a simple method to  
handle this, it obviously needs more error checking, but don’t want to  
reinvent the wheel if not necessary.

def AND(s, m)  
t = s.dup  
for i in 0…(s.size \<= m.size ? s.size : m.size)  
t[i] = (s[i] & m[i]).chr  
end  
return t  
end

On a related note, is there any way to create a string from a hex number  
other than separating each two digits and using .chr to convert them to  
a number and adding them to the string? If I have a string such as  
0x7FFFFFFFFFFF I have to use something like str1 = 0x7F.chr followed by  
5 str1 \<\< 0xFF.chr which seems to be unnecessarily clumsy.

---

<div class="post-metadata">

**Author:** ![Michael\_WSRyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/53a042/32.png) [@Michael\_WSRyder](https://www.ruby-forum.com/u/Michael_WSRyder)\
**Post date:** [January 28, 2008, 11:10am UTC](https://www.ruby-forum.com/t/logical-operations-on-strings/127325/2 "2008-01-28T11:10:16Z")

</div>

2008/1/28, Michael W. Ryder [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> return t  
> end

I believe this implementation is flawed because it returns a string  
that is too long if self.size \> m.size.

This is what I’d probably do

class String  
def &(s)  
t = “”  
[size, s.size].min.times do |i|  
t \<\< (self[i] & s[i])  
end  
t  
end

def |(s)  
t = “”  
[size, s.size].max.times do |i|  
t \<\< ((self[i] || 0) | (s[i] || 0))  
end  
t  
end  
end

Now you can do

irb(main):020:0\> 0.chr | “a”  
=\> “a”  
irb(main):021:0\> 0.chr | “abc”  
=\> “abc”  
irb(main):022:0\> 0.chr & “abc”  
=\> “\000”  
irb(main):023:0\> a=“s”  
=\> “s”  
irb(main):024:0\> a|=“123”  
=\> “s23”  
irb(main):025:0\> a&=“\012”  
=\> “\002”

> On a related note, is there any way to create a string from a hex number  
> other than separating each two digits and using .chr to convert them to  
> a number and adding them to the string? If I have a string such as  
> 0x7FFFFFFFFFFF I have to use something like str1 = 0x7F.chr followed by  
> 5 str1 \<\< 0xFF.chr which seems to be unnecessarily clumsy.

I am not sure which direction you mean (there is no such thing as a  
“hex number” in Ruby, a number is a number, hex is just one  
representation - internally they are most likely stored binary). Does  
this help?

irb(main):001:0\> 123.to\_s 16  
=\> “7b”  
irb(main):002:0\> “%04x” % 123  
=\> “007b”  
irb(main):003:0\> “7b”.to\_i 16  
=\> 123

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![Michael\_WSRyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/53a042/32.png) [@Michael\_WSRyder](https://www.ruby-forum.com/u/Michael_WSRyder)\
**Post date:** [January 28, 2008, 9:39pm UTC](https://www.ruby-forum.com/t/logical-operations-on-strings/127325/3 "2008-01-28T21:39:22Z")

</div>

On 1/28/08, Michael W. Ryder [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> codes for printing using hex and it is easier for me to use them that  
> way. In Business Basic to enter a group of hex characters into a string  
> I just use A$=$1B2C062C$ to create a 4 character string. No need to  
> enter each character individually.

Are you looking for something like this?

irb(main):010:0\> [“414243”].pack(‘H\*’)  
=\> “ABC”  
irb(main):011:0\> [“7FFFFFFFFFFF”].pack(‘H\*’)  
=\> “\177\377\377\377\377\377”  
irb(main):012:0\> A=[‘1B2C062C’].pack(‘H\*’)  
=\> “\e,\006,”

-Adam

---

<div class="post-metadata">

**Author:** ![Michael\_WSRyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/53a042/32.png) [@Michael\_WSRyder](https://www.ruby-forum.com/u/Michael_WSRyder)\
**Post date:** [January 29, 2008, 12:06am UTC](https://www.ruby-forum.com/t/logical-operations-on-strings/127325/4 "2008-01-29T00:06:04Z")

</div>

Adam S. wrote:

> > codes for printing using hex and it is easier for me to use them that  
> > irb(main):012:0\> A=[‘1B2C062C’].pack(‘H\*’)  
> > =\> “\e,\006,”
> 
> -Adam

That is much better, I will have to read up on pack and template strings  
now but at least I have a starting point. It’s not as concise as what I  
am used to but it is usable. Thank you for pointing this out.

---

<div class="post-metadata">

**Author:** ![Michael\_WSRyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/53a042/32.png) [@Michael\_WSRyder](https://www.ruby-forum.com/u/Michael_WSRyder)\
**Post date:** [January 28, 2008, 9:05pm UTC](https://www.ruby-forum.com/t/logical-operations-on-strings/127325/5 "2008-01-28T21:05:36Z")

</div>

Robert K. wrote:

> > end  
> > return t  
> > end
> 
> I believe this implementation is flawed because it returns a string  
> that is too long if self.size \> m.size.

Actually I designed it that way so that I could change only part of the  
original string without having to create a mask of 0xFF for the  
remaining characters. Your implementations look a little cleaner than  
my first try and I will probably use them in the finished version. I  
still wonder why these weren’t implemented in Ruby as I have been using  
them for over 25 years in other languages.

> irb(main):025:0\> a&="\012"  
> representation - internally they are most likely stored binary). Does  
> this help?

The reason I asked is that sometimes it is easier for me to think in hex  
when creating masks for logical operations. Plus, I learned the PCL  
codes for printing using hex and it is easier for me to use them that  
way. In Business Basic to enter a group of hex characters into a string  
I just use A$=$1B2C062C$ to create a 4 character string. No need to  
enter each character individually.

---

<div class="post-metadata">

**Author:** ![Michael\_WSRyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/53a042/32.png) [@Michael\_WSRyder](https://www.ruby-forum.com/u/Michael_WSRyder)\
**Post date:** [January 29, 2008, 9:38am UTC](https://www.ruby-forum.com/t/logical-operations-on-strings/127325/6 "2008-01-29T09:38:06Z")

</div>

2008/1/28, Michael W. Ryder [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Robert K. wrote:
> 
> > I believe this implementation is flawed because it returns a string  
> > that is too long if self.size \> m.size.
> 
> Actually I designed it that way so that I could change only part of the  
> original string without having to create a mask of 0xFF for the  
> remaining characters.

Ah, ok, then this was on purpose. Personally I’d consider an element  
that is not there as 0x00 for OR and AND - that’s why I did it this  
way.

> Your implementations look a little cleaner than  
> my first try and I will probably use them in the finished version. I  
> still wonder why these weren’t implemented in Ruby as I have been using  
> them for over 25 years in other languages.

Since Ruby is so flexible chances are that you will find an equally  
easy (or easier) way. 🙂

> The reason I asked is that sometimes it is easier for me to think in hex  
> when creating masks for logical operations. Plus, I learned the PCL  
> codes for printing using hex and it is easier for me to use them that  
> way. In Business Basic to enter a group of hex characters into a string  
> I just use A$=$1B2C062C$ to create a 4 character string. No need to  
> enter each character individually.

Then #pack and #unpack are your friends (see Adam’s reply). You could  
easily put that in a method if you want a more concise representation,  
e.g.

def h(s)  
[s.to\_str].pack ‘H\*’  
end

irb(main):005:0\> h ‘212223’  
=\> “!"#”  
irb(main):006:0\> h ‘414243’  
=\> “ABC”  
irb(main):010:0\> h %Q{414243}  
=\> “ABC”  
irb(main):011:0\> h %q{414243}  
=\> “ABC”

Note also, that you can use hex constants in Ruby:

irb(main):001:0\> 0x7b  
=\> 123

but it seems you are more after construction of strings.

Kind regards

robert
