[Question]
  [
Given two strings as input, return the result of XORing the code-points of one string against the code points of the other.
For each character in the first input string, take the code-point (e.g. for `A`, this is 65) and XOR the value against the corresponding index in the second string and output the character at the code-point of the result. If one string is longer than the other, you **must return the portion of the string beyond the length of the shorter**, as-is. (Alternatively, you may pad the shorter string with `NUL` bytes, which is equivalent.)
See the following JavaScript code for an example:
```
const xorStrings = (a, b) => {
  let s = '';
  // use the longer of the two words to calculate the length of the result
  for (let i = 0; i < Math.max(a.length, b.length); i++) {
    // append the result of the char from the code-point that results from
    // XORing the char codes (or 0 if one string is too short)
    s += String.fromCharCode(
      (a.charCodeAt(i) || 0) ^ (b.charCodeAt(i) || 0)
    );
  }
  return s;
};
```
[Try it online!](https://tio.run/##bVNtT9swEP68/IobX@KsbZp2vKoDxEolPmyCgiYmtYW5idtkMnGwHRo0@O3d2U5pealqXc5@nudedPeXPlAVy6zQrVwkbLmMRa40VEJeaZnlcwWHQGgTpgEcHsE/D4AzDebW93seuu02lIqBThlwkc@ZBDGznl4IWAiZKNACYsrjklNdA1k@1@kKKJkquUapmZBAjHyG8lEPzTf4SXUa3tGK0NCxMJX6K0BEoxHYpGwetChYnmxoriLEKZUwk@LOeVhnqxBZrtGlusYqC1hJ/T6/xOLXZMNRQDDBCLIZiJyBsv2BzNQnQKVC6sDSFTQOwXUvNJp9FOgjn9hXwHaGcX11okkWwNMTRAHcAJl@9GBZQQ/Ns@m3ZLqUOaie94z9H@HNyD9jnIum3wT/WkiefPYnTRfKlOKPq85sXEUULUMb4ZniSfw111AX55c/TtdMxz3@cgQNB6TTOGEGGHW6X7ffAodXw@uhA3KxYDKmyoC3Do59B9pCggH@urgYXPZPrgYOrJnSRhT1PsGrnwHbV4szMXcM8GB/b3fnbXQsZ9@VGG3j6ZoyfbjNhb6FTqcTHXRfBbN2Q@JFJNo8L4EN5eR7/3TwnlMUxWldSdQxuHv1DmeBjm@Bf@K6lOHwA6Ar1JsgNMSFGNA4JWRkNnBiV9Dsp@As5GLuBmq9qm5PvRctneJw4t/s1QPlWUJ1JnIcXv4IFBcFn7BDOFH3ZSYZ@jk8itINe60SSlZwGjPSHt2Mq27UGld7bNKeN4HENh1vlbs/Hlc@NID4kTHx5igHoRYuR9LZDQJvXXGoyikuEml1V7fGIqS3XP4H "JavaScript (Node.js) – Try It Online")
## Test cases
```
Input                         Output
['Hello,', 'World!']          '\x1f\x0a\x1e\x00\x0b\x0d'
['Hello', 'wORLD']            '?*> +'
['abcde', '01234']            'QSQWQ'
['lowercase', "9?'      "]    'UPPERCASE'
['test', '']                  'test'
['12345', '98765']            '\x08\x0a\x04\x02\x00' _not_ 111092
['test', 'test']              '\x00\x00\x00\x00'
['123', 'ABCDE']              'pppDE'
['01', 'qsCDE']               'ABCDE'
['`c345', 'QQ']               '12345'
```
## Rules
* The two input strings will only ever be code-points 0-255.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") so the shortest solution, in each language, wins.
  
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 4 bytes
```
O^/Ọ
```
[Try it online!](https://tio.run/##y0rNyan8/98/Tv/h7p7///9HqycmJaekqusoqBsYGhmbqMcCAA "Jelly – Try It Online")
Takes input as a list of the two strings, e.g. `['abcde', '01234']`.
### How?
```
O    # ord: cast to number (automatically vectorizes)
 ^/  # Reduce by XOR. XOR automatically applies to corresponding elements
         and pads as desired to work if the two strings are different lengths
   Ọ # chr: cast to character (vectorizes once again)
```
[Answer]
# [Raku](https://github.com/nxadm/rakudo-pkg), 4 bytes
```
*~^*
```
[Try it online!](https://tio.run/##XY9fCwFREMXffYrhwdQS966/m9jElgfFEh4sWvZuqcvV7hZKvvq6g4Sp0zzM75yZOYlI1tPDFfIhtFPjvjbSVib2rxDC7VD2liXD9lblkjPvDiFUEcj9UcTpEgdCSlXEIuBCRTLI4go@hd6Fh96F@boL3ZnWVivAzNtIvvNoMux/27TRNjpQIMrf7gJBFONmpfpHuVN34RIl1VlEOz8mMmfZ@JrnnjTOxmNn0utOHSITEScU95v0znsONUSrakRZzUa99rdU3998/cSqWib9hbA5qmQDnHNmmQ8 "Perl 6 – Try It Online")
Raku has a built-in operator for XORing strings, along with string AND, OR and bitshift. This is a Whatever lambda that takes two parameters.
[Answer]
# perl -Mfeature=say,bitwise -nl, 22 bytes
```
$.%2?($;=$_):say$;^.$_
```
[Try it online!](https://tio.run/##K0gtyjH9/19FT9XIXkPF2lYlXtOqOLFSxTpOTyX@/3@P1JycfB2u8PyinBRFLjCPq9w/yMeFKzEpOSWVy8DQyNiEKye/PLUoObE4lcvSXl0BDLhKUotLuLhA0qZclhbmZqb/8gtKMvPziv/r@qalJpaUFqXaAi3SScosKc8sTv2vm5cDAA)
This is way more characters than I first hoped for. If it weren't for those pesky newlines, the 9 character `say<>^.<>` would do.
## How does it work?
For odd input lines, it saves the current line of input (without the trailing newline due to the `-n` and `-l` switches) into `$;`. For even lines, it `xor`s the previous line (`$;`) and the current line (`$_`), and prints it. The `^.` operator does required bitwise string operation.
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), 15 [bytes](https://github.com/abrudz/SBCS)
```
80⎕DR≠⌿↑11⎕DR¨⎕
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///qKM97b@FwaO@qS5BjzoXPOrZ/6htoqEhmH9oBZACqfjPmcal7pGak5Ovo66gHp5flJOiqM4FFwSKlfsH@bhAhBKTklNSgUIGhkbGJhChnPzy1KLkxGKQsKW9uroCGEDkSlKLS4DCEA5IiylIkYW5mak6AA "APL (Dyalog Unicode) – Try It Online")
As the OP clarified that the input codepoints will be in the range of 0-255, it is possible to manipulate the underlying data bits directly. Such a string is guaranteed to have data type `80` (8-bit char array), so we convert it to data type `11` (1-bit boolean array) to access the bits, XOR them, and convert back to data type `80`.
```
80⎕DR≠⌿↑11⎕DR¨⎕  ⍝ Full program, input: two string literals on a line
        11⎕DR¨⎕  ⍝ Convert each string literal to bit array
       ↑         ⍝ Promote to matrix, padding with 0 as needed
     ≠⌿          ⍝ Bitwise XOR
80⎕DR            ⍝ Convert back to 8-bit char array
```
---
# [APL (Dyalog Extended)](https://github.com/abrudz/dyalog-apl-extended), 17 bytes
```
⎕UCS⊥≠⌿⍤2⊤↑⎕UCS¨⎕
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT9dNrShJzUtJTfn/qKM97f@jvqmhzsGPupY@6lzwqGf/o94lRo@6ljxqmwiROLQCSINU/udM41L3SM3JyddRV1APzy/KSVFU54ILAsXK/YN8XCBCiUnJKalAIQNDI2MTiFBOfnlqUXJiMUjY0l5dXQEMIHIlqcUlQGEIB6TFFKTIwtzMVB0A "APL (Dyalog Extended) – Try It Online")
Well, the task involves converting char to charcode and back AND converting from/to binary, but all current implementations having `⍢` have some quirks so it can't be used here. So here is the very literal implementation of the task.
```
⎕UCS⊥≠⌿⍤2⊤↑⎕UCS¨⎕  ⍝ Full program, input: two string literals on one line
           ⎕UCS¨⎕  ⍝ Convert to codepoints
          ↑        ⍝ Promote into a 2-row matrix, padding zeros as necessary
                   ⍝ (doing on characters give spaces which is 0x20, not 0)
         ⊤  ⍝ Convert each number to binary
     ≠⌿⍤2   ⍝ Bitwise XOR
    ⊥       ⍝ Convert the binary back to integers
⎕UCS        ⍝ Convert the integers back to chars
```
[Answer]
# [J](http://jsoftware.com/), 14 bytes
```
XOR@,:&.(3&u:)
```
[Try it online!](https://tio.run/##bY9PT8JAFMTv/RRPDzzR2uwWUGiiCG2NBwJsicEDCZb@OZjGVloD376@7gKpaTeZvD38ZibzVV4bGMOTBQg6MLBI9wbY3uy1/Fh4L7rVMW56nV@rW3ZLfIuSJNURYsB1uk/CK4TLm08NwM2Rx5sj8@lGdBlpRwpRU15pPSy8mVNznrzj22e4I9DfBWEkQcbNXr8JipVYCwKT9BDtAz9X8GiMJxTP4Pty6Xr2ZOUSXER5Ibl/ebVUCWhYVQ5U4PDxYdBspzlDNZH1SWY1E2H7nRZb4JyzkVkrUx9oC2F1qWJpmUxtx23zZFnmVEsYl9xP3uQUqBI0/AzOU4RoBdXWPw "J – Try It Online")
### How it works
```
XOR@,:&.(3&u:)
        (3&u:) strings -> code points
      &.       do right part, then left part, then the inverse of the right part
    ,:         pad shorter one with zeros by making a table
XOR@           XOR the code points
        (3&u:) revert back code points -> string
```
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~60~~\$\cdots\$ ~~55~~ 54 bytes
Saved ~~2~~ 4 bytes thanks to [AZTECCO](https://codegolf.stackexchange.com/users/84844/aztecco)!!!
Saved ~~a~~ 2 bytes thanks to [ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat)!!!
```
#define f(a,b)for(;*a+*b;b+=!!*b)a+=putchar(*a^*b)!=*b
```
[Try it online!](https://tio.run/##jVHbToNAEH3vVywY43IxQq1ag9jUtokPJvYS0wepuguLkiAgYEps@u24s0tr2yc3GebsXM6ZZfzTd9@v66OAhVHCUIiJSbUwzbGjE0OnDjVcRdGpRgw3@y79D5JjnbzwgOLqtP4kUYI1tGohfiCpo5IV5St5XiAXrdR7FsepqZpIIgCE@gEDEKdLlvukEBfoAm@3zzsXBwFwlg3fNx@ya@dQjjZy8zSPAwUql4/Th6Fs5IwArnsnSBy4iED36nJPqn83GI4AfBUNmEz@ZtpTZVXGqpIFja5X2aFXWYR7xr3FjXILoLun3yJDkM0mc8H3NB6PpoP@bLQrzsu7ksLqcGsDjYpkwto1KM6yTA4oR25G41tDOEpKFCUBq/hgltPAG1REPywN8WZu7awJiOdoDjIMUblZJZws51whVj31uPC4mPRewmGzY9GyMDc7kFfN2TKE@J@FW6mES4DA9v/ula5b6/oX "C (gcc) – Try It Online")
[Answer]
# [Python 3.8](https://docs.python.org/3.8/), 71 bytes
```
f=lambda a,b:chr(ord(a[0])^ord(b[0]))+f(a[1:],b[1:])if a and b else a+b
```
[Try it online!](https://tio.run/##bZLfT8IwEMef3V9RfbkWCNkQFUgmUSHxwUQmMTww1HbrwpKyznZR/OuxN6ZRtMn1Luvnez/alR/VWheng9Lsdlmo@EaknPCOGCVrQ7VJKV/6K/aEkcCItTP3KRitOgJ3lmfE8UVKBJHKSsLbYpdvSm0qYqRnQwMAS7iVSukOdAgstFHpMazI94J4G2Tx1ufOS@d9Z8JZCl4jRN37/cPd5KfMCcetS9JGiosklUj5Qe@0f0BF82gRIaX0uzQJt0ieDMewPz@paXiczaYPN1fzKZKVtBWm@52pyVcfOghLnSE1HFycnx0Udf0P9jP5fWc9nAvIc6GrZxIEgT/s/ShT@4NS0NzEtzUlkb@6vplM/wjKspzU3fsBQq/2H@hL66iXpGk/iv5S@9k893behlfJWprQyG6iN2WuJDVA42W3NY5XLLZtGgPGwNwOzOPWSvf4ShZ0OwobdTfLi5QrRS1jYRj4XqYN/mUkL8h25B2VJi8qmtEWlW9cUc4Qq0PB2O4T "Python 3.8 (pre-release) – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), ~~8~~ 7 bytes
thanks to [Kevin Cruijssen](https://codegolf.stackexchange.com/users/52210/kevin-cruijssen) for a byte!
```
Ç0ζε`^ç
```
[Try it online!](https://tio.run/##yy9OTMpM/f//cLvBuW3ntibEHV7@/3@0UkKysYmpko5SYKBSLAA "05AB1E – Try It Online")
### Commented
```
	 implicit input          ["QQ", "`c345"]
Ç        convert to charcodes    [[96, 99, 51, 52, 53], [81, 81]]
  ζ      Zip with filler ...     [[96, 81], [99, 81], [51, "0"], [52, "0"], [53, "0"]]
 0       ... zero
   ε     Map ...                   [96, 81]
    `      Dump on stack           96, 81
     ^     XOR                     49
      ç    Convert to character    "1"
         implicit output         ["1", "2", "3", "4", "5"]
```
[Answer]
# Excel, ~~158 153~~ 108 bytes
(Not counting closing parens)
## Compatibility Notes:
* Minimum version: `CONCAT()` came to be in later versions of [Excel 2016](https://support.microsoft.com/en-us/office/concatenate-function-8f8ae884-2ca8-4f7a-b093-75d702bea31d) (from `CONCATENATE()`).
## The Formulae
* Inputs: `A1`, `B1`
* A2: `=MIN(LEN(A1:B1))`, 14
* B2: `=LEN(A1)-LEN(B1)`, 15
Code (124):
```
=CONCAT(CHAR(BITXOR(CODE(MID(A1,SEQUENCE(A2),1)),CODE(MID(B1,SEQUENCE(A2),1)))))&RIGHT(IF(B2>0,A1,B1),ABS(B2))
```
One unfortunate caveat is that Excel ignores non-printable characters in cells. Alternatively, if you'd rather I use "\xXX" characters, I have this:
```
=CONCAT("\x"&DEC2HEX(BITXOR(CODE(MID(A1,SEQUENCE(A2),1)),CODE(MID(B1,SEQUENCE(A2),1))),2))&RIGHT(IF(B2>0,A1,B1),ABS(B2))
```
at 118 bytes. This just prints all XOR'ed characters as "\xXX" characters and leaves the trailing characters alone. Eg: `Hello!` and `World!!` produce `\x3F\x2A\x3E\x20\x2B\x00!`
### How it Works:
1. The `SEQUENCE(A2)` effectively creates a range of (1..A2). As far as I can tell, I cannot re-use this by caching it in a cell, which is why I had to use it twice.
2. Each item is then converted to numbers with `CODE()` and `BITXOR()`ed against each other.
3. The `CHAR()` converts this to a character, while `DEC2HEX(...,2)` converts it to a 2 width 0-padded hex number.
4. `CONCAT()` puts the array together
5. `RIGHT(...)` tacks on the trailing characters of the longer string.
[Answer]
# Java 10, 109 bytes
```
(a,b)->{int A=a.length,B=b.length;if(A<B){var t=a;a=b;b=t;A^=B^(B=A);}for(;A-->0;)a[A]^=A<B?b[A]:0;return a;}
```
I/O as arrays of characters.
[Try it online.](https://tio.run/##dVPfT9swEH7nr7j5ZY6aRmUb@1HPoAQmbdIAMR72UFrtnLiQLiSd7bRCVf/2YjveqsDIg33n77473@fLAlc4XBS/d3mFWsM5lvXmAKCsjVRzzCVcOBcgv0M1mUJOOwPjbhcRs/D2wC7aoClzuIAa@I5iLKLh8cbmgZRjUsn61tzFGRfBZOWcpp@zaLNCBYYjQy6Y4IalM57NaMbTiG3njaIsHQ6PRyzCSTqdcUs5EdYaj5iSplU1INvumKu/bEVl64drrJqygHvbDb02qqxv7d0x6loxUhtKvsqqamISA/nZqKp4RXwnPdSB68sf38/6GIq8kA4bHb55@66PVc1aqhy1xz@dvAb/9WPc6uD@qct15FkfP7w/@j/D709ZDkiz07MvfWR06IA/@hnwKw@Frq7Is9fzsvm4TjbAOBgiqHf9oI28T5rWJEsLmKqm5Fu9bI0eww0hAxyQGwJYF94Tzvtb/ymVksvWWOb4n0BhypTUbWWAQ53kFBPTnNrzVCl8oFEs@n5g2nRuPJtCLhtra0eWa3/cZQtzN@3C3WS52Sx5D2VlN2z7PJNyOggx1mQvSuCadQU7tWjHiLwWdJ/NdjpY2D8uaU1ZJb4DbdsJpH2cJUYvqWarhWfb7h4B)
**Explanation:**
```
(a,b)->{             // Input as 2 character arrays as parameters as well as return-type
  int A=a.length,    //  `A`: the length of the first array `a`
      B=b.length;    //  `B`: the length of the second array `b`
  if(A<B){           //  If the length of `a` is smaller than `b`:
    var t=a;a=b;b=t; //   Swap the arrays `a` and `b`
    A^=B^(B=A);}     //   And also swap the lengths `A` and `B`
                     //  (`a`/`A` is now the largest array, and `b`/`B` the smallest)
  for(;A-->0;)       //  Loop index `A` in the range [`A`, 0):
    a[A]^=           //   Bitwise-XOR the `A`'th value in `a` with, and implicitly cast
                     //   from an integer codepoint to a character afterwards:
      A<B?           //    If index `A` is still within bounds for `b`:
       b[A]          //     XOR it with the `A`'th codepoint of `b`
      :              //    Else:
       0;            //     XOR it with 0 instead
  return a;}         //  Return the modified `a` as result
```
Note that we cannot use a currying lambda `a->b->` here, because we modify the inputs when swapping and they should be (effectively) final for lambdas.
[Answer]
# [Factor](https://factorcode.org/), 48 bytes
```
: f ( s s -- s ) 0 pad-longest [ bitxor ] 2map ;
```
[Try it online!](https://tio.run/##Vc1PT8IwGAbwO5/icRflMDJQQMeBKBAgIRggxoMxoXTvkFjW0b4E/PSzgwqxh/759XnaVEjWpnhbjKfDGFvBX/gmk5GCpd2eMkn2uqvRkY2wyA0x/@RmkzE6lfE0htQJhWut0iJGiju4EsLQTVVEyEUSKp2tyTI@sNrwURt8orEVOTpFMCKldIDgXRuV3ASuX6tc8PA6n/S9iZVMyFlUb9w/eFP6QEYKW/pT9xan4e/YfejYn8pSs0w9tlvN/4nz8pdy8PzS6w@8RHUHO3uFpTw/NJudoPgF "Factor – Try It Online")
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 66 bytes
```
f=(a,b)=>b[a.length]?f(b,a):(B=Buffer)(a).map((c,i)=>c^B(b)[i])+''
```
[Try it online!](https://tio.run/##XY9fT8IwFMXf@RSVl7ZSx0BQkAwissQYI38Ww8OYSdu1MFNXsk3BTz9b@oDhJif34f7OuTmf9IeWvMj21U2uU1HXMkCUMByMWUw9JfJttUsmEjFC8QOaBtNvKUWBEcXeF90jxElmWP4xRQzHWYJbENajuAFADJ@FUppAAuBaFyq9ggkBbtptADfHjtwcfWq2MNs3YkYpPHut9TBfvc7OTuedXI9By4GU8VRY0O90b3uX4DJarpcOVPogCk5LCzeHE@igpjFY8H2xCFdPj1Ho4EqUlQ39n3dOPV1PnP3Zt@BwcH/Xv/xu6gxcRb9n1LU1YSNpeFIXIeU7hGJKAEswCMaA67zUSnhKb9FLNH/zyqrI8m0mf5FEFsNmRvUf "JavaScript (Node.js) – Try It Online")
[Answer]
# Scala, 64 bytes
```
(a,b)=>(""/:a.zipAll(b,'\0','\0').map(x=>x._1^x._2))(_+_.toChar)
```
[Try it online!](https://tio.run/##dc1LT8MwDADge39FyKWJqEo7Nh6VOlQ2JA4gNDhw4FHcNB1FWVvSiI1N@@2lyXbKRA625c92WgYCujr74kyheyirjZPzAi36ioCctxFKpITflycly2r@RtHGcX5AoCJChOya3i7ReLwvUNwR8LK@QTA@icBfl00iBMk89zVwTaD@AhqyiscrPw3f@zCglKTHqa/qySdI2jX9JSUqUhB8y4WoPewh/FxLkR9hSh2btS4fHu@mFkLGcq4xCAenQwtFveSSQWsGLq9cZJ41pHirtFttfW5k9i7Oz0b/7Jh8sKcluZ5MbywKQi3f7aF8sP1ns5kWZ7vt/gA "Scala – Try It Online")
Run with
```
val f: ((String,String)=>String) = ...
println(f("01","qsCDE"))
...
```
Uses `zipAll` to zip the input strings with null bytes as padding, then XORs, finally using `foldLeft` shorthand `/:` to turn the whole thing back into a string.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 6 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
```
cÈ^VcY
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=Y8heVmNZ&input=J2FiY2RlJwonMDEyMzQn)
```
cÈ^VcY     :Implicit input of strings U & V
c          :Map the charcodes in U
 È         :by passing each one at index Y through the following function
  ^        :  Bitwise XOR with
   VcY     :  Charcode at index Y in V
```
[Answer]
# [Lua](https://www.lua.org/), 105 bytes
```
i,a,b=0,...print(a:gsub('.',load'i=i+1return a.char((...):byte()~(b:sub(i,i):byte()or 0))')..b:sub(#a+1))
```
[Try it online!](https://tio.run/##bVJfa9swEH@2P4VGKJKJYqKs3VYPM7alsMFgdC97MIbJtrwKNCuRZMoo7VfP7qSY9mHGYP3@3J3vTmaWJ2N7achIamKsHJrmpLnkXb3lZVkenJ4Ck9VvP3eMlpSjhepar4VTYXYTkWV/Jx1jYC6q7m9QrHhiXYV@zfVCWUe2RUGLskzSSq5FUZzaNs9T@QOUj8UWwkgP53Ge@qDtlLRYJM@k98oFtnoA@EjqmgggN5sDY/TiSItqtO6PTGYQMBEkB5SraVjSB@WDB/ohz@gXZYzllBP60zozvKLvFxK5@@8/vu0jJbt@UEhtxe71ZaSMvVeulx7pprn@QEl82hZFrIH26MSQK0TX796@uaIv9fg9exB//PR5fxOJrUB89Av@1Z@T3N4CfoT5wGB1Lfgq9rMRfEcGCz3HHqXgRO6gySg2uuXLaS3axTRqh4PORpbsMLFI4XXAFaCwAwFmnGd6TH7ylFQS7tSUZ5lyzsIdoHs9jsqpKRCn/GxgwvEHp8MMx4sjvFX6PG8pVeUpL49ZcWtxVRmu9OuLaE7sHAD@N8M5FCJP/wA "Lua – Try It Online")
Taking two strings as arguments, this program calls per-character replace on one of them with essentially XOR function, then appends potentially missing fragment from second string (occurs if it is longer) and prints the result. TIO includes test suite.
[Answer]
# PHP, 36 bytes
```
[,$a,$b]=$argv;echo"$a\r$b\r",$a^$b;
```
Usage:
```
$ php -r '[,$a,$b]=$argv;echo"$a\r$b\r",$a^$b;' -- 'ABCDE' '123';echo
> pppDE
```
Explanation: first output string A, then carriage return `\r`, output string B, then another carriage return, then output the XOR (which truncates to the shorter of the 2 strings). Any characters of the longer string will have already been printed.
# PHP 7.4, 32 bytes
Using new arrow function syntax.
```
fn($a,$b)=>($a|$b^$b)^($a^$a|$b)
```
Explanation:
In PHP binary operators, only the `|` will keep the longest string length and pad with `NUL`s. So we XOR string B with itself, leading to a string with NUL bytes of the same length as B, then OR that with A. This will pad A with NUL bytes and use the length of B, if B is longer than A. We do the same with B, and only *then* XOR.
Edits:
* arrow function variant
* missed the requirement of outputting the longest string
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal), 4 bytes
```
C÷꘍C
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=&code=C%C3%B7%EA%98%8DC&inputs=%5B%22test%22%2C%20%22%22%5D&header=&footer=)
Because Vyxal auto-pads lol.
## Explained
```
C÷꘍C
C     # convert each character in each string to it's ordinal value
 ÷꘍   # bitwise xor each item
   C  # and convert the result back to characters
```
Alternatively, using Keg mode:
### [Vyxal](https://github.com/Vyxal/Vyxal) `K`, 1 byte
```
꘍
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=K&code=%EA%98%8D&inputs=%22lowercase%22%0A%229%3F%27%20%20%20%20%20%20%22&header=&footer=)
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 33 bytes
```
Ｆ⌈ＥθＬι«Ｆθ«≔ζη≔∧‹ιＬκ℅§κιζ»℅⁻｜ηζ＆ηζ
```
[Try it online!](https://tio.run/##RU5BCoMwEDzrKxYvrpA@oHgotqeCYu/iIWiqSzXWJFax@PZUpbRz2Z1hZneKmqui4421904BJnyidmjX@cSeQSxkZWqkYAW8XWf39PvqRFpTJXFmUAfhn0eyxFhojfSLP4KAQapKkrzByFxlKSZ8MNjOMpi39OI6N0XS4GXtwwsjFCYkB41nMiNpkSqsNyuDr7C92ZUVobtYm2V@041CFVwLn4F3PPkAXp7bw6v5AA "Charcoal – Try It Online") Link is to verbose version of code. Takes input as an array of two strings. Explanation:
```
Ｆ⌈ＥθＬι«
```
Loop over the longer length of the strings.
```
Ｆθ«
```
Loop over the strings.
```
≔ζη
```
Save the result of the previous loop, if any.
```
≔∧‹ιＬκ℅§κιζ
```
Get the ordinal at the current index, if that is less than the current string.
```
»℅⁻｜ηζ＆ηζ
```
Emulate bitwise XOR by subtracting the bitwise AND from the bitwise OR, then convert back to a character.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~80~~ ~~72~~ 69 bytes
```
lambda*a:''.join(map(lambda x,y:chr(ord(x or'\0')^ord(y or'\0')),*a))
```
[Try it online!](https://tio.run/##dZBdb4IwFIbv/RWdXhxgZClMNzXZjBOTLVmiaBZvyFwFjC5IO6gRfj1rBZSJa3J6ctrnPV8s5Rsamtn6yckCslt5RCN9gLtvug2VHWFK/ogSPe27m0ihkackiEbgYFA/ZZSWkaprRFWz1lvI9hz9dyZ7Lr4bDRZtQ47WCrz6QUB10BEsaBR4N1CAKmqJG5zEWDsJJsL7wmNhK2EeXGSQCQ6T2bsFp1JFhoH2jG4rOFm5ni9xbJj37Rpuz@2FXcEDevAjl8RS0uwNCr5Z4h/T6Xg2Gs7HFQn3Yy4LwMXsheT4faZlFx2J97qPD51aP2LYbr4A3BZmyiUAWoaUL5FhGLhn1gsffb1wsb@T/W1CCocvI2t8RckYs6oTYkPSP/EFXeJ5mjP@5RYj2vY1PN9A9gs "Python 2 – Try It Online")
Uneven lengths are annoying...
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), ~~86~~ 81 bytes
```
$k=[char[]]($args[1]);([byte[]]([char[]]($args[0])|%{$_-bxor$k[$i++%$k.Length]}))
```
[Try it online!](https://tio.run/##K8gvTy0qzkjNyfn/XyXbNjo5I7EoOjZWQyWxKL042jBW01ol09bAWiM6qbIkFSSBpsIgVrNGtVolXjepIr9IJTtaJVNbW1UlW88nNS@9JCO2VlPz////ngqJuQppiSX/I/NLFRKLUhVKMjLzAA "PowerShell – Try It Online")
-5 bytes thanks to @mazzy
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~44~~ 43 bytes
```
x(o,r)char*o,*r;{*o|*r&&x(o+1,r+1,*o^=*r);}
```
[Try it online!](https://tio.run/##bZFRS8MwEMff@ynOykaSVWkr@pLNJx98EARftw66LN0CNRlpqx1bP3tMurY4ayBw/H93/7tL2N2OMXMrJMurLYd5UW6Fut8/e78lLeTuWmPl8cCtZGqkAo3ZPtVEBUTTE1FnoqdTq8@iQNtL1HpBNKaNEbKEz1RI5IJU71gArhCIjb@WCYaTB/a02qbK0mX8@JTAAk5hQ6/IZkSco6DeJc4AOXe4WcADBs3LSkuIOmq3YYcjcv4BtI2jBNM/aNOh2KGW1V2Fg72WKQ1I2DFCCgLmrj7nEvWmcD6PZGcIs5nod@3nFQWTNq1tshQJxgN152A/oMyQv1rVkzCu/QD6PDrk8bzg/xZN2Ci/ucw/2Eq/X6l7rJB6jTGvPM@V@X7/eHv5AQ "C (gcc) – Try It Online")
Uses recursion, note that to print strings containing the null byte one will have to manage the strings as arrays. (See the footer of the link for an example)
# [C (gcc)](https://gcc.gnu.org/), ~~50~~ 49 bytes
```
x(o,r)char*o,*r;{*o|*r&&x(o+!!*o,r+!!*r,*o^=*r);}
```
[Try it online!](https://tio.run/##bZFRT4MwEMff@RQ3zJa2Q8Mw@tLNJx98MDHxdcMEusKaYLsUUBbgs2PLYHFiX3r5/@7@d9ey25Sx7kZIlpV7Duu82At1d3hyfktayPRaY8XpyI3UVUh5GrNDpInyiKY1UQ3Ri4XRl7OZ0bS9tEfUx4ZoTNtOyAI@IyGRDSKdMg9sORATf21DDLUD5vRaXCbRNnh4DGEDtd/SKxJPiHUU1DnHCSDrDrMN3GPQvCi1hNVAzU7seELW34O@8SrE9A@KBxRY1LNqqLBw1BKlAQkzhk9BwNrWZ1yi0RSaZiJbQ1guxbjrOK/ImTRpfZOtCDG@UHuO5huKBLm7XTX3g8r1YMyjlzye5fzfojmb5Lfn@S@20h1XGh7Lp07bdS88y1T3/fb@@vwD "C (gcc) – Try It Online")
Slightly safer version (doesn't read past end of strings, requires enough memory to exist past them though - a la `strcpy`).
# [C (gcc)](https://gcc.gnu.org/), ~~61~~ 60 bytes
```
x(b,o,r)char*b,*o,*r;{*o|*r&&x(b+1,o+!!*o,r+!!*r,*b=*r^*o);}
```
[Try it online!](https://tio.run/##dZHBbsIwDIbvfQrDBErSbCpM2yWw0w47TJq0KxSpDSlE6hIUylYEffYubikaY/Ol1v859m9X3q6krG@0kfluqWCyLZba3q2fgp@S02Z1qcliv1FeqkuScssdlevEsZQzy5kTB2aPzA2HHoYjbsNez@sOP46zdMrcglkqqlqbAj4SbQgmiVtJDtgHmM8/ZzGFQwA@Gi3dZcls/PAYwxQOUSUuSPovkVcEZ2kRtHkGBOdCbwr3FJwqds7A6ET94nKzJziZQ2NpFFPxC6UnNEbUsBJlv0r7Dks6klkHRHszkQANE@ySK0O61nA8XsnYFsJQd7foXOutNL6sMTfTMaVnirHxf6zISH8@LwfRuOzz9hS6s4@h8q3689FAXtVXrf9zW9PvVjqdLBJBVdcvKs9t/fX2/vr8DQ "C (gcc) – Try It Online")
As safe as any standard C function taking a buffer, at the cost of a few more bytes.
-1 byte from each thanks to ceilingcat!
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 7 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
ôM◙L╞@←
```
[Run and debug it](https://staxlang.xyz/#p=934d0a4cc6401b&i=123%0AABCDE)
[Answer]
# [Husk](https://github.com/barbuz/Husk), 11 bytes
```
ż§oc-¤nc¤vc
```
[Try it online!](https://tio.run/##yygtzv7//@ieQ8vzk3UPLclLPrSkLPn///9KOfnlqUXJicWpSv@VLO3VFRSUAA "Husk – Try It Online")
Unfortunately [Husk](https://github.com/barbuz/Husk) doesn't have a bitwise XOR command (that I could find), so we need to do:
arg1 OR (`v`) arg2 minus arg1 AND (`n`) arg2, costing an extra 5 bytes...
[Answer]
# x86 machine code, 29 bytes
Machine code:
```
00000034: 31 d2 e3 08 8a 11 41 41 84 d2 e1 fe ac 84 c0 75  1.....AA.......u
00000044: 06 e3 09 89 ce 31 c9 30 d0 aa eb e4 c3           .....1.0.....
```
Commented assembly:
```
        .intel_syntax noprefix
        .globl .strxor
        // Doesn't follow standard calling convention.
        // Input:
        //      EDI: Output buffer large enough for longest string
        //      ESI, ECX: Null terminated strings to XOR
        // Output:
        //      NON-null terminated string stored in EDI.
.strxor:
.Lloop:
        // Always clear EDX.
        xor     edx, edx
        // We mark the end of the shorter string
        // by setting ECX to null.
        jecxz   .Lskip_ecx
.Lno_skip_ecx:
        // Read a byte from ECX into DL.
        mov     dl, byte ptr [ecx]
        // Increment twice because LOOPZ decrements.
        inc     ecx
        inc     ecx
        // Was it '\0'?
        test    dl, dl
        // If so, set ECX to NULL by using LOOPZ in place.
        // CMOVZ ECX, EAX also works, but needs P6.
        // This works with i386 and is the same size.
.Lclear_ecx:
        loopz   .Lclear_ecx
.Lskip_ecx:
        // Load from ESI and autoincrement
        lods    al, byte ptr [esi]
        // Test for '\0'
        test    al, al
        jnz     .Lno_swap
.Lswap: // '\0' found
        // If ECX is null, we are at the end of both strings.
        jecxz   .Lend
        // Otherwise, we swap ESI and ECX, and then clear ECX.
        // Set ESI to ECX.
        mov     esi, ecx
        // And set ECX to NULL.
        xor     ecx, ecx
        // fallthrough
.Lno_swap:
        // XOR the two bytes together
        xor     al, dl
        // Store to EDI and autoincrement
        stos    byte ptr [edi], al
        // Loop unconditionally.
        jmp     .Lloop
.Lend:
        ret
```
[Try it online!](https://tio.run/##tVdtb9s2EP6uX3HzVjgB/J6067xiRRZnWAA3bpt0NVpnGUXRNlOZ1EiqtoP99@yOki0r0vptAiyavFfePTyeQmaXj4@cOfgF5jIWnWt49QouJr8FkD8dqZyI7@xWObYBpRMj5nJTkBexDmPoWGc22uyXu10YaWFV08Fcx7Feg3VMRcxEwFkcS7UArtVXoZzUqnModqmS1A0PV/xzMbocwiR1SIQwnc@FgZiZhQChdLpYohVc0GohrENTBg1UVVxftuDifDqEqzSOwQmzkoo5EeUCFpyG6eT9oWBmserO1eSqrWq14KANzqQinztBHplh0BnHWiclVWfxmm0t8Fgwg9zTIhAo4UcRbVr0OpT6KGDFzBdwS9p9BHru/9qlNuhNze7DLVjhHDmH26ddkuuFsXvBNw@Uy7H9IpM7nKGzSt/tZiWf3wsWAUOdTsDc6JVXiRjRMBoXKlf6qx@juJWxJs7AZ9R1W841N2KFIAC3llxAKDhLrYDxZPL2E0Qip9pCr1Q8iwvffHONwsQsSAfNWa/5er/uCB@5X1Fc8mUOVrcoULsgXX0Yjyl2qaXIZT5hVpOYcVGC7PmbyR@fSArhdTYFFlsNa22@WNw7wlUJEVl4@6Ikc7OUNmOCtXRLkCcvXwCeEMBln022wpd8QEudsQdIOROEpSxne2JQ5K@UsbHGjGWpur70NljqtNzF/kAluokPK@fMylLObiiCdNoosJW4kiwr4nqvHrIq4eG0Zgn5iMOQNJEC1JSq6EkePKKsB2kL1gKYwZ87xHuoMWT5qa3DsSjrnKCoWUsrvDpyYB8KnzX6gyxqdxLPp6VcXRMmkB8xUSLtQI4haj1F3xmqfIKlmtPNNxXBOZZHtzRU1IJ92Er5xBLlY@HW2ueJ6tZC0BYrBlgF5tdUnfxORt/CAhYxj4UDHETytpRbjyydQKqwkkeSCjm6vj1IxyrJk09gDXxWio0Y4YIAdbTpCYr7xApOqqDRcWLjOqmynOppowUNtsH3s8ToRSidPXREbDjVDYpKiGD3aOQ6EjAdBZ0V40bD2w8358D3QklqlzTOeDWdDLNyWl0OcblfXfY5tEmVEJX4sUT6sbd52Su80MnOZNDB8KyCnbs3F9c3by4I4/0WvQd7Gb8RgGajWYn0yTzoFxHuMMvlAzRmpKQRDOopg0ZwclBWBCsg3Q@r67TbQXgYe4QektWCipjyKVBMfhWAV1tNDJMy4G0aHhCsrBqkZJyEVQH25OjwPAaZJlYQ7rFJoOd0XhwPvlyUeE9LByzS1LfgoYhThJAvU7gznTUfuNU9L95QO5tVBy3pDutwIcuAoYYog36lh1ob6cSRdREab2Uq0T60oX/8v8L20O9a4LIoqt9lDTopoiKWK0ndib/sepv5vIUVwF@l2MftCc2Zaj5VRcy7wxHk7eYddpPGBdlQ5C4/NND4XWDP2aKa8VGbOPqu8R8sxLGevB@PahhYyCNBDL3@4OS0hgG7WmE4s57pp9fNjFzDSOWIeGpIpPq5l3/544vn35D1Y608Uc9@PR9d1JB7faL@beups794bv3du0Y9nvr1eOrVowO/Gx4XnEN7dTKANt99UbR19k8H1NBA@2w3LXgxkU7iRGkEeyzDnINEaefB95CwLX59YB/gso8GusNWW1/uE2Fi5MjxhI2DVgm2Bo6Fscjbq3OsodsY@wfLWSKsv/IPRXRqPNCy7m6p42gHSYb92xo/WKgR6/qL5R9vENoJ1gbbPfr85@ehNze8naGG2@Ou9dP5UWM22zzrDaYYYW2iox/6x8fdhfjZdomvO1PdRTN4/Bc "Bash – Try It Online")
The code reads two null terminated strings from `esi` and `ecx`, and stores the NON null terminated string in `edi`.
The logic is probably easier to see in the equivalent C code.
```
void strxor(char *dst, const char *src1, const char *src2)
{
    for (;;) {
        char x = '\0';
        if (src2 != NULL) {
            x = *src2++;
            if (x == '\0') { // eos
                src2 = NULL;
            }
        }
        char y = *src1++;
        if (y == '\0') {
            if (src2 == NULL) { // both eos
                return;
            } else { // src2 is longer
                src1 = src2;
                src2 = NULL;
            }
        }
        *dst++ = x ^ y;
    }
}
```
I don't null terminate because null bytes naturally show up in the output and it saves a byte.
I may also add a version with explicit lengths which accepts null bytes, but the solution would be significantly less elegant.
[Answer]
# [Perl 5](https://www.perl.org/), 14 bytes
```
sub f{pop^pop}
```
[Try it online!](https://tio.run/##K0gtyjH9/7@4NEkhrbogvyAOiGv/FydWKqRpKCUmJaekKukoGRgaGZsoaVpzQcVLUotLgMIIEfWc/PLUouTE4lR1HQUlS3t1BTAAKvj/L7@gJDM/r/i/rq@pnoGhAQA "Perl 5 – Try It Online")
[Answer]
# Scala 3, ~~30~~ 29 bytes
```
a=>b=>a zipAll(b,0,0)map(_^_)
```
[Try it online](https://scastie.scala-lang.org/0szOKel0TIqe2F3tK8I03g)
# Scala 2, ~~41~~ ~~39~~ 38 bytes
Used infix notation to turn `.map` into just `map`
```
a=>b=>a zipAll(b,0,0)map(a=>a._1^a._2)
```
Inputs and output are lists of integers
[Try it online](https://scastie.scala-lang.org/5uxNZJaHQS6GjkNQ7RPctg)
]