Skip to main content
We’ve updated our Terms of Service. A new AI Addendum clarifies how Stack Overflow utilizes AI interactions.
Code Golf

Return to Answer

Fix typo
Source Link
EasyasPi
  • 5.4k
  • 20
  • 23

I may also add a version with explicit lengths which accepts null bytes, but the solution would be significantly less elegant.

I may also add a version with explicit lengths which accepts null bytes, but the solution would be significantly less elegant.

Source Link
EasyasPi
  • 5.4k
  • 20
  • 23

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!

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.

AltStyle によって変換されたページ (->オリジナル) /