Logical XOR of strings

Discussion in 'Ruby' started by Michael W. Ryder, May 30, 2006.

  1. I have looked in the documentation and can't find a way to XOR two
    strings. I want to use this to obfuscate an identifier in a database so
    that it can't be read. In the language I have used for over 20 years I
    just say A$=XOR(B$,C$) to get this result. In Ruby I expect it would be
    something like a = string1.xor(string2). Obviously this does not work,
    but is there another way short of converting everything to numbers,
    using the ^ operator on them, and then converting the result back to a
    string?
     
    Michael W. Ryder, May 30, 2006
    #1
    1. Advertising

  2. Michael W. Ryder

    Dave Burt Guest

    Michael W. Ryder wrote:
    > I have looked in the documentation and can't find a way to XOR two
    > strings. I want to use this to obfuscate an identifier in a database so
    > that it can't be read. In the language I have used for over 20 years I
    > just say A$=XOR(B$,C$) to get this result. In Ruby I expect it would be
    > something like a = string1.xor(string2). Obviously this does not work,
    > but is there another way short of converting everything to numbers,
    > using the ^ operator on them, and then converting the result back to a
    > string?


    No, but it's not hard to implement:

    class String
    def ^(other)
    other = other.to_str rescue (raise TypeError, "can't convert to string")
    ret = ""
    size.times {|i| ret << (self ^ other rescue self) }
    ret
    end
    end

    Cheers,
    Dave
     
    Dave Burt, May 30, 2006
    #2
    1. Advertising

  3. Dave Burt wrote:
    > Michael W. Ryder wrote:
    >> I have looked in the documentation and can't find a way to XOR two
    >> strings. I want to use this to obfuscate an identifier in a database so
    >> that it can't be read. In the language I have used for over 20 years I
    >> just say A$=XOR(B$,C$) to get this result. In Ruby I expect it would be
    >> something like a = string1.xor(string2). Obviously this does not work,
    >> but is there another way short of converting everything to numbers,
    >> using the ^ operator on them, and then converting the result back to a
    >> string?

    >
    > No, but it's not hard to implement:
    >
    > class String
    > def ^(other)
    > other = other.to_str rescue (raise TypeError, "can't convert to string")
    > ret = ""
    > size.times {|i| ret << (self ^ other rescue self) }
    > ret
    > end
    > end


    Here's my take:

    class String
    def ^(key)
    key = key.to_str
    result = ""
    for i in 0...length
    result << (self ^ key[i % key.length])
    end
    result
    end
    end

    Kind regards

    robert
     
    Robert Klemme, May 30, 2006
    #3
  4. Robert Klemme wrote:
    > Dave Burt wrote:
    >> Michael W. Ryder wrote:
    >>> I have looked in the documentation and can't find a way to XOR two
    >>> strings. I want to use this to obfuscate an identifier in a database so
    >>> that it can't be read. In the language I have used for over 20 years I
    >>> just say A$=XOR(B$,C$) to get this result. In Ruby I expect it would be
    >>> something like a = string1.xor(string2). Obviously this does not work,
    >>> but is there another way short of converting everything to numbers,
    >>> using the ^ operator on them, and then converting the result back to a
    >>> string?

    >>
    >> No, but it's not hard to implement:
    >>
    >> class String
    >> def ^(other)
    >> other = other.to_str rescue (raise TypeError, "can't convert to
    >> string")
    >> ret = ""
    >> size.times {|i| ret << (self ^ other rescue self) }
    >> ret
    >> end
    >> end

    >
    > Here's my take:
    >
    > class String
    > def ^(key)
    > key = key.to_str
    > result = ""
    > for i in 0...length
    > result << (self ^ key[i % key.length])
    > end
    > result
    > end
    > end
    >
    > Kind regards
    >
    > robert


    Both of those worked great. Thank you. Now I just have to figure out
    what they say. The only difference in Ruby from my past experience is
    that the returned strings include octal characters for the non-printable
    characters but I can live with that.
     
    Michael W. Ryder, May 30, 2006
    #4
  5. Michael W. Ryder wrote:

    > Both of those worked great. Thank you. Now I just have to figure out
    > what they say. The only difference in Ruby from my past experience is
    > that the returned strings include octal characters for the non-printable
    > characters but I can live with that.


    I don't know what you mean by that. You requested XORing of strings -
    and if you XOR two strings you likely end with non printable chars.
    That's totally expected behavior. Can you elaborate?

    Cheers

    robert
     
    Robert Klemme, May 30, 2006
    #5
  6. Robert Klemme wrote:
    > Michael W. Ryder wrote:
    >
    >> Both of those worked great. Thank you. Now I just have to figure out
    >> what they say. The only difference in Ruby from my past experience is
    >> that the returned strings include octal characters for the
    >> non-printable characters but I can live with that.

    >
    > I don't know what you mean by that. You requested XORing of strings -
    > and if you XOR two strings you likely end with non printable chars.
    > That's totally expected behavior. Can you elaborate?
    >


    Instead of having an ascii character 21 (decimal) in the string the
    string would display \025. I don't know if the stored string just
    included the character 21 or the octal representation. Using nine
    character strings would at a worst case show 36 characters for the
    result. I am not sure how much it would use internally or how it would
    load into a database such as MySQL. I am still trying to learn Ruby as
    I want to use if for customer access to their accounts.

    > Cheers
    >
    > robert
     
    Michael W. Ryder, May 30, 2006
    #6
  7. Michael W. Ryder wrote:
    > Robert Klemme wrote:
    >> Michael W. Ryder wrote:
    >>
    >>> Both of those worked great. Thank you. Now I just have to figure out
    >>> what they say. The only difference in Ruby from my past experience
    >>> is that the returned strings include octal characters for the
    >>> non-printable characters but I can live with that.

    >>
    >> I don't know what you mean by that. You requested XORing of strings -
    >> and if you XOR two strings you likely end with non printable chars.
    >> That's totally expected behavior. Can you elaborate?
    >>

    >
    > Instead of having an ascii character 21 (decimal) in the string the
    > string would display \025. I don't know if the stored string just
    > included the character 21 or the octal representation. Using nine
    > character strings would at a worst case show 36 characters for the
    > result.


    You probably have a different understanding of what you want to do than
    I. When I hear string XOR this means byte wise (or character wise) XOR
    and this does not result in a longer string. Are you rather looking for
    encoding the result base64 to ensure only printable characters? Do you
    want to have hex representation of XOR results? How do you want to
    combine characters from both strings? What exactly do you want the
    method to perform?

    Kind regards

    robert
     
    Robert Klemme, May 30, 2006
    #7
  8. Michael W. Ryder

    Dave Burt Guest

    Michael W. Ryder wrote:
    > Both of those worked great. Thank you. Now I just have to figure out
    > what they say. The only difference in Ruby from my past experience is
    > that the returned strings include octal characters for the non-printable
    > characters but I can live with that.


    You're running into a feature here. If you're using IRB, or
    string.inspect, or p(string), then what you're looking at is a
    displayable version of the string.

    The octal escapes are legal in a Ruby string literal, and represent a
    single character in the string.

    If you use puts(string) or print(string) or string.display, the
    "interesting" characters (such as "\n" for newline, "\t" for tab, "\025"
    for ASCII char 025) will be output.

    "123".length #=> 3
    "\n\t\025".length #=> 3
    puts "\n\t\025"
    =>
    §

    So, the data you want is in the strings; you have our bitwise (not
    "logical" as in the message subject) xor.

    HTH,
    Dave
     
    Dave Burt, May 30, 2006
    #8
  9. Dave Burt wrote:
    > Michael W. Ryder wrote:
    >> Both of those worked great. Thank you. Now I just have to figure out
    >> what they say. The only difference in Ruby from my past experience is
    >> that the returned strings include octal characters for the non-printable
    >> characters but I can live with that.

    >
    > You're running into a feature here. If you're using IRB, or
    > string.inspect, or p(string), then what you're looking at is a
    > displayable version of the string.
    >
    > The octal escapes are legal in a Ruby string literal, and represent a
    > single character in the string.
    >
    > If you use puts(string) or print(string) or string.display, the
    > "interesting" characters (such as "\n" for newline, "\t" for tab, "\025"
    > for ASCII char 025) will be output.
    >
    > "123".length #=> 3
    > "\n\t\025".length #=> 3
    > puts "\n\t\025"
    > =>


    This makes it a lot clearer. I am still trying to learn the language
    and the differences between it and my primary language. The language I
    normally use does not display the unprintable characters so the
    displayed string is often shorter than the input string. I wasn't
    expecting irb to display the unprintable characters.


    > §
    >
    > So, the data you want is in the strings; you have our bitwise (not
    > "logical" as in the message subject) xor.
    >
    > HTH,
    > Dave
     
    Michael W. Ryder, May 30, 2006
    #9
  10. Robert Klemme <> wrote:
    > Michael W. Ryder wrote:
    > >
    > > Instead of having an ascii character 21 (decimal) in the string the
    > > string would display \025. I don't know if the stored string just
    > > included the character 21 or the octal representation. Using nine
    > > character strings would at a worst case show 36 characters for the
    > > result.

    >
    > You probably have a different understanding of what you want to do than
    > I. When I hear string XOR this means byte wise (or character wise) XOR
    > and this does not result in a longer string. Are you rather looking for
    > encoding the result base64 to ensure only printable characters? Do you
    > want to have hex representation of XOR results? How do you want to
    > combine characters from both strings? What exactly do you want the
    > method to perform?


    His concern is that ruby is actually storing "\021" internally as %w(\ 0
    2 1).join. Don't worry - that's merely a display artefact:

    irb(main):004:0> a = "\021"
    => "\021"
    irb(main):005:0> p a
    "\021" # <---- inspecting the string, so it shows a human-friendly
    # representation of the character
    irb(main):006:0> puts a
    # <------ unprintable character here


    martin
     
    Martin DeMello, May 31, 2006
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Christopher Benson-Manica

    Why isn't there a logical XOR operator?

    Christopher Benson-Manica, Feb 3, 2004, in forum: C Programming
    Replies:
    80
    Views:
    3,381
    CBFalconer
    Feb 6, 2004
  2. dataangel

    Why can't I xor strings?

    dataangel, Oct 8, 2004, in forum: Python
    Replies:
    50
    Views:
    1,177
    Andrew Dalke
    Oct 13, 2004
  3. Phil Frost

    Re: Why can't I xor strings?

    Phil Frost, Oct 8, 2004, in forum: Python
    Replies:
    1
    Views:
    323
    Alex Martelli
    Oct 11, 2004
  4. yaipa
    Replies:
    0
    Views:
    1,061
    yaipa
    Feb 16, 2007
  5. Martin Wells

    Logical XOR

    Martin Wells, Sep 21, 2007, in forum: C Programming
    Replies:
    14
    Views:
    872
    David Thompson
    Oct 8, 2007
Loading...

Share This Page