logical operands on strings

Ali Çehreli acehreli at yahoo.com
Sun Jan 12 11:22:57 PST 2014


On 01/12/2014 10:21 AM, Erik van Velzen wrote:
> I would like to do this:
>
>      string one = x"315c4eeaa8b5f8aaf9174145bf43e1784b";
>      string two = x"c29398f5f3251a0d47e503c66e935de81230b59b7a";
>      string three = one ^ two;
>
>
> The closests I've been able to get is:
>
>      string three = xor(one, two);
>
>      string xor(string one, string two) {
>          int len = min(one.length, two.length);
>          string result;
>          for(int i=0; i<len; i++) {
>              result ~= one[i] ^ two[i];
>          }
>          return cast(string)result;
>      }
>
> Question 1: is there a more elegant way to implement the function xor?
> (foreach-ish or std.algorithm)
>
>
> Then I tried to add operator overloading:
>
>      string opBinary(string op)(string lhs, string rhs) {
>          static if( op == "^" )
>              return xor(lhs, rhs);
>          else static assert(false, "operator not possible");
>      }
>
> But it doesn't invoke this function.
>
> Question 2: how would I implement "^" for strings?

XOR is not a valid operation on a UTF-8 code unit. ;) It makes more 
sense to work with ubyte arrays. However, I found two usability issues 
with it:

1) std.conv.to did not work from string to ubyte[]; so, I wrote a function.

2) Array-wise operations does not support the following syntax

     auto three = one[] ^ two[];

Otherwise, ^= works with slices:

import std.stdio;

ubyte[] toBytes(string s)
{
     return cast(ubyte[])s.dup;
}

void main()
{
     ubyte[] one = x"55".toBytes;
     ubyte[] two = x"aa".toBytes;

     ubyte[] three = one.dup;
     three[] ^= two[];

     assert(one == x"55");
     assert(two == x"aa");
     assert(three == x"ff");
}

Ali



More information about the Digitalmars-d-learn mailing list