1

I have two absurdly long binary Variables a and b with the assumption that they have the same length. What I want is simple: XOR them and store in a new variable, that's it. As I got fed up with different errors like Expression.Convert: Object of type 'System.Int64' cannot be converted to type 'System.Int32' or Value was either too large or too small for a UInt32 or Arithmetic overflow error converting expression to data type int, I will do it on my own.

  1. Iterate bit by bit (char by char) through the a and b.
  2. XOR bit of a with bit of b on pos i and concatenate this newly created XORed bit to a new variable newXorVar

Here's my code:

@echo off 
setLocal enableDelayedExpansion

set a=01101000011001010110010101000010101010101010101010111010101010101010101010100000000001101111000010101010101101100011011000110111111010101000001
set b=01110111011011110111001001101100011001000010000111011000110010101100101010000101010101010101100011011000110110001100100001010110110001101100011

set pos=0
set newXorVar=""

:NextChar
  ::check if each character can be reached --> okay
  echo Char %pos% is !a:~%pos%,1! and !b:~%pos%,1! 
  ::XOR each bit --> does not work
  set /a xorAB=!a:~%pos%,1!^!b:~%pos%,1!
  ::echo does not work --> not the desired output
  echo !xorAB! 
  newXorVar=!newXorVar!!xorAB!
  set /a pos=pos+1
  if "!a:~%pos%,1!" NEQ "" goto NextChar

::output computed newXOR var
echo !newXorVar!

Can anybody help me out fixing my code so that it works?

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
Ferit
  • 558
  • 1
  • 5
  • 19
  • 4
    Use `set /a "xorAB=!a:~%pos%,1!^^!b:~%pos%,1!"` Note the quotes and the double-caret: `^^`. And you forgot the `set` command in this line: `newXorVar=!newXorVar!!xorAB!` – Aacini May 02 '20 at 11:24
  • We can only help you to fix your code, if you specifically explain to us how your code is failing to achieve something it is supposed to achieve. Your question does not explain that, so we have nothing to help you with. Please note, that if you're looking for a co-writer, you're on the wrong site. – Compo May 02 '20 at 11:25
  • Thank you, Aacini! I was close enough. Question: Why did I have to double-caret? – Ferit May 02 '20 at 11:33
  • Because `^` by itself is the escape character in batch. You need the second one to escape it. – SomethingDark May 02 '20 at 11:58
  • 1
    @Aacini - both quotes ***and*** escape? It should be one or the other, but not both – dbenham May 02 '20 at 13:25
  • 2
    @dbenham, I guess you missed that delayed expansion is enabled here, so quotes protect the `^` from being recognised after the `%`-expansion phase, but the delayed expansion phase then also consumes `^` to escape `!`-characters; without quotes I think `^^^^` would be necessary... – aschipfl May 02 '20 at 19:14
  • @aschipfl. Indeed I did miss that critical point. Thanks for correcting me and giving the explanation. Its something I should have caught, but for the community at large the explanation is very helpful. – dbenham May 02 '20 at 19:57

1 Answers1

0

As already pointed out by user Aacini in his comment, the problem is caused by the this line:

set /a xorAB=!a:~%pos%,1!^!b:~%pos%,1!

Since the caret (^) is the escape character, it needs to be protected. This can be achieved by doubling or by quotation:

rem // Double the `^` in order to escape itself:
set /a xorAB=!a:~%pos%,1!^^!b:~%pos%,1!
rem // Or quote the whole expression to protect the `^`:
set /a "xorAB=!a:~%pos%,1!^!b:~%pos%,1!"

However, since you have delayed expansion enabled, which also treats the ^ as escape character, you need to protect it once again in order for it to be preserved:

rem // Quadruple the `^` in order to escape itself:
set /a xorAB=!a:~%pos%,1!^^^^!b:~%pos%,1!
rem // Or double it and quote the whole expression to protect them:
set /a "xorAB=!a:~%pos%,1!^^!b:~%pos%,1!"

For more details refer to this revealing thread: How does the Windows Command Interpreter (CMD.EXE) parse scripts?

aschipfl
  • 33,626
  • 12
  • 54
  • 99