g | x | w | all
Bytes Lang Time Link
014Uiua241224T032632Znyxbird
006Vyxal241024T223833Zemanresu
005Nekomata230912T035857Zalephalp
038Wolfram Language Mathematica v13.3+230905T001159Zatt
009Itr230815T073434Zbsoelch
037Pyt230208T020052ZKip the
009Vyxal230102T232545Zlyxal
00805AB1E220924T131318ZKevin Cr
006Jelly220923T235245ZUnrelate
016Jelly160501T024201ZLeaky Nu
287MMIX210502T060445ZNoLonger
029JavaScript Node.js210415T050942Zl4m2
006ARM Thumb2 NEON210130T003439ZEasyasPi
053R210130T002325ZDominic
012Jelly210129T145128Zcaird co
042JavaScript Node.js200921T181948Zuser
097GNU Assemblerx86_64 Mac OS X180606T145935ZJustinCB
029gnuplot170416T183520ZSerge Bo
368GAP151219T180136ZLiam
090Ceylon151217T205451ZPaŭlo Eb
030Julia150516T025615ZAlex A.
063Go150518T171533Zstonith
032Dart150515T234243Zlrn
040Mathematica150516T175233Zalephalp
007x86 machine code150516T123726Zuser5550
035Perl 35 Bytes150516T070721Zprimo
011Z80150516T073429ZCJ Denni
073Ruby150516T031826ZAtsby
035Python 2150516T030451ZSp3000
038C150515T205349ZBrainSte
050Haskell150515T231454Znimi
066Python 2150515T204724Zsirperci
013CJam150515T210303ZOptimize
068golflua150515T211322ZKyle Kan
062Java150515T204028ZYpnypn
014J150515T204417Zrandomra
012Pyth150515T204837Zisaacg

Uiua, 14 bytes

°⋯⊕/≠⊞+.°⊏/⊞×⋯

Try it!

°⋯⊕/≠⊞+.°⊏/⊞×⋯
                ⋯ # convert to binary
            /⊞×   # multiplication table
   ⊕  ⊞+.°⊏      # for each diagonal:
     /≠            #   reduce with xor
°⋯                # convert from binary

Vyxal, 6 bytes

bƒÞƈ∷B

Try it Online! Port of UnrelatedString's Jelly answer, go upvote that!

b      # Binary digits
 ƒÞƈ   # convolve
    ∷  # Take modulo 2
     B # Convert back from binary

Nekomata, 5 bytes

ᵃƂ×Öƃ

Attempt This Online!

ᵃƂ×Öƃ
ᵃƂ      Convert both inputs to binary digits
  ×     Convolve
   Ö    Modulo 2
    ƃ   Convert back to decimal

Wolfram Language (Mathematica) v13.3+, 38 bytes

(F=2~FiniteField~+##;F@#2F@#)@"Index"&

Input [a, b].

Version 13.3 introduced FiniteField, which is nicer to golf with than FiniteFields`GF. Getting an integer out of a FiniteFieldElement is still a little verbose, though.

test cases

Itr, 9 bytes

BàBC*µRxB

online interpreter

Explanation

            ; implicit input
BàB         ; convert input to bit lists
   C*µRx    ; polynomial multiplication in F2[X]
        B   ; convert bit-list to number
            ; implicit output

Pyt, 37 bytes

ɓąƖĐŁř⁻↔2⇹^**ĐŁ2%¬?ŕ:ŕÁ0á;ĐŁ`ŕʁ⊻ĐŁ⁻łŕ

Try it online!

Takes two integers a,b on separate lines

The following is worked on a=13, b=14

Code Stack Description
ɓąƖ [1,1,0,1] Pushes the ąrray corresponding to the ɓits of 13
ĐŁř⁻↔2⇹^* [8,4,0,1] Converts array to corresponding powers of 2
* [112,56,0,14] Multiplies the array by 14
ĐŁ2%¬? [112,56,0,14], True does the array have an even length?
ŕ [112,56,0,14] If so, pop the boolean check
:ŕÁ0á (skipped in this run) Otherwise, append a 0 to the array
;ĐŁ`ŕʁ⊻ĐŁ⁻ł [70], 0 ʁeduce the array using XOR () while the Łength of the resulting array is greater than 1
ŕ [70] ŕemove the 0; implicit print

Vyxal, 9 bytes

₌0b(dn⁰*꘍

Try it Online!

Ports the 05AB1E answer, so go upvote that too

Explained

₌0b(dn⁰*꘍
₌0b       # Push 0 and the binary of the first input
   (      # to each bit:
    d     # double the top of the stack
     n⁰*  # multiply the bit by the second input
        ꘍ # and bit xor

05AB1E, 8 bytes

Îbv·yI*^

Try it online or verify all test cases.

Explanation:

Î         # Push 0 and the first input
 b        # Convert it to a binary string
  v       # Loop over each bit `y` of this string:
   ·      #  Double the current integer
    y     #  Push bit `y`
     I*   #  Multiply it by the second input
       ^  #  Bitwise-XOR the two together
          # (after the loop, the result is output implicitly)

Jelly, 7 6 bytes

Bæc/ḂḄ

Try it online!

-1 thanks to Jonathan Allan

Takes a list of [a, b]. (The dyadic equivalent is the very fun-looking BæcḂḄɓB.)

B         Convert a and b to their binary digits,
 æc/      and convolve them.
    Ḃ     Take each mod 2
     Ḅ    and convert from binary.

Jelly, 16 bytes

Ḥ⁴BL’¤Ð¡U×"⁴B¤^/

Try it online!

MMIX, 28 bytes (7 instrs)

(jelly xxd)

00000000: e3020000 7aff0001 c60202ff 3f000001  ẉ£¡¡z”¡¢İ££”?¡¡¢
00000010: 37010101 5b00fffc f8030000           7¢¢¢[¡”‘ẏ¤¡¡

Disassembly:

clmul   SETL $2,0       // r = 0
0H      ZSOD $255,$0,$1 // loop: t = a odd? b : 0
        XOR  $2,$2,$255 // r ^= t
        SRU  $0,$0,1    // a >>= 1
        SLU  $1,$1,1    // b <<= 1
        PBNZ $0,0B      // iflikely(a) goto loop
        POP  3,0        // return r

You could get a 128-bit answer out of this with about three more instructions, I think.

JavaScript (Node.js), 29 bytes

f=(x,y)=>x&&f(x>>1,y)*2^x%2*y

Try it online!

Similar to https://codegolf.stackexchange.com/a/50246/

ARM Thumb-2 (NEON), 6 bytes

Eat my Thumb, pclmullqlqdqdqdqdq. ARM has boring builtins, too!

ef80 0e01 4770

Assembly code:

        .syntax unified
        .arch armv7-a
        .fpu neon
        .thumb
        .globl xormul_boring_neon
        .thumb_func
xormul_boring_neon:
        // q0[0-8] = d0[0-8] @ d1[0-8]
        vmull.p8 q0, d0, d1
        bx       lr

Input: two 8-bit values in d0 and d1 Output: the 16-bit product in q0

This actually multiplies 8 packed bytes together.

ARM Thumb-2, manual, 14 bytes

Ok, to make up for it, here is a fully scalar version which does a 32x32 multiply with a 32-bit result.

2300 0849 bf28 4043 0040 d1fa 4770

Assembly code:

        .syntax unified
        .arch armv6t2
        .thumb
        .globl xormul_scalar
        .thumb_func
        // r3 <- r0 @ r1
xormul_scalar:
        // acc <- 0
        movs    r3, #0
.Lloop:
        // test each bit in y by using lsrs carry-out
        lsrs    r1, r1, #1
        // was the bit set?
        it      cs
        // if so, acc ^= x
        eorcs   r3, r0
        // shift x left
        lsls    r0, r0, #1
        // loop while x is non zero
        bne     .Lloop
.Lend:
        // return in r3
        bx      lr

Equivalent C code:

uint32_t xormul_scalar(uint32_t x, uint32_t y)
{
    uint32_t acc = 0;
    do {
        if (y & 1)
            acc ^= x;
        y >>= 1;
    } while ((x <<= 1));
    return acc;
}

The numbers to be multiplied are in r0 and r1, and the result is in r3.

It is a fairly basic shift and xor loop.

Yet another case of lsls and lsrs being far too useful than they deserve to be.

Try it online! (sorta): demo in Travis

R, 53 bytes

f=function(x,y)`if`(y,bitwXor(x*y%%2,2*f(x,y%/%2)),0)

Try it online!

Jelly, 12 bytes

BJ’2*U×B{×^/

Try it online!

How it works

BJ’2*U×B{×^/ - Main link. Takes a on the left, b on the right
B            - Binary representation of a
 J           - Replace each element with its index
  ’          - Decrement
   2*        - Raise each to the power 2
     U       - Reverse
       B{    - Yield the binary representation of a
      ×      - Multiply the bits by the powers
         ×   - Multiply b by the results
          ^/ - Reduce by XOR

JavaScript (Node.js), 42 bytes

Port of the Java answer. Go upvote that!

x=>y=>(g=i=>i&&g(--i)^x*((y>>i)%2)<<i)(32)

Try it online!

GNU Assembler(x86_64 Mac OS X), 97 bytes

This is a proper function that can be called from C:

.text
.globl _f
_f:
movq %rdi,%xmm0;movq %rsi,%xmm1;pclmulqdq $0,%xmm1,%xmm0;movq %xmm0,%rax;ret

& can be tested with this C program:

#include <stdio.h>
int f(int a, int b);
#define p(a,b) printf("%d %d %d\n", a, b, f(a, b))
int main(void)
{
    p(0,1);
    p(1,2);
    p(9,0);
    p(6,1);
    p(3,3);
    p(2,5);
    p(7,9);
    p(13,11);
    p(5,17);
    p(14,13);
    p(19,1);
    p(63,63);
}

Note that on Mac OS X, you have to use clang -x c to compile it as C & not C++.

For linux(if I remember right), the code would be 95 bytes:

.text
.globl f
f:
movq %rdi,%xmm0;movq %rsi,%xmm1;pclmulqdq $0,%xmm1,%xmm0;movq %xmm0,%rax;ret

Strangely enough, this version is actually longer than defining the function in inline assembly, but that one was longer than the pure C solution we already have, so I decided to try assembly.

edit

If it's counted by the assembled size(excluding any labels &c.), then it's

x86_64 Assembler, 22 bytes:

0:  66 48 0f 6e c7          movq         %rdi,  %xmm0
5:  66 48 0f 6e ce          movq         %rsi,  %xmm1
a:  66 0f 3a 44 c1 00       pclmullqlqdq $0,    %xmm1,%xmm0
10: 66 48 0f 7e c0          movq         %xmm0, %rax
15: c3                      ret

gnuplot, 29 bytes

m(a,b)=a<1?0:a%2*b^m(a/2,b*2)   

just like in Dart (see above)

GAP, 368 Bytes

For mathematicians, this is multiplication in the polynomial ring F_2[x], identifying polynomials with natural numbers by evaluating at x=2 as a polynomial over Z.

Sure, let's do that! (this is only loosly golfed, the point was more to move into F2[x] and do the calculations more than any attempt at being a winning entry)

Here's the code

f:=function(i,j)R:=PolynomialRing(GF(2));x:=IndeterminatesOfPolynomialRing(R);x:=x[1];a:=function(i)local n,r;r:=0*x;while not i=0 do n:=0;while 2^n<=i do n:=n+1;od;n:=n-1;r:=r+x^n;i:=i-2^n;od;return r;end;b:=function(r)local c,i,n;i:=0;n:=0;for c in CoefficientsOfUnivariatePolynomial(r) do if c=Z(2)^0 then n:=n+2^i;fi;i:=i+1;od;return n;end;return b(a(i)*a(j));end;

Here's the ungolfed code with explanation:

xor_multiplication:=function(i,j)           
    R:=PolynomialRing(GF(2));
    x:=IndeterminatesOfPolynomialRing(R);
    x:=x[1];
    to_ring:=function(i)
        local n,r; 
        r:=0*x;
        while not i=0 do
            n:=0;
            while 2^n<=i do
                n:=n+1;
            od;
            n:=n-1;
            r:=r+x^n;
            i:=i-2^n;
        od;
        return r;
    end;
    to_ints:=function(r)
        local c,i,n;
        i:=0;n:=0;
        for c in CoefficientsOfUnivariatePolynomial(r) do
            if c=Z(2)^0 then
                n:=n+2^i;
            fi;
            i:=i+1;
        od;
        return n;
    end;
    return to_ints( to_ring(i)*to_ring(j));
end;

Okay, so first off, we create the univariate polynomial ring over the field F2 and call it R. Note that GF(2) is F2 in GAP.

R:=PolynomialRing(GF(2));

Next, we are going to assign the GAP variable x to the indeterminate of the ring R. Now, whenever I say x in GAP, the system will know I am talking about the indeterminate of the ring R.

x:=IndeterminatesOfPolynomialRing(R);
x:=x[1];

Next, we have two functions, which are inverse maps of each other. These maps are both onto, but they are not structure preserving, so I couldn't figure out a better way to implement them in GAP. There almost certainly is a better way, if you know it, please comment!

The first map, to_ring takes an integer and maps it to its corresponding ring element. It does this by using a conversion to binary algorithm, where every 1 that would appear in binary is replaced by an x^n where n is the appropriate power that 2 would take if the number was indeed binary.

    to_ring:=function(i)
        local n,r; 
        r:=0*x;                 # initiate r to the zero element of R
        while not i=0 do        # this is a modified binary algorithm
            n:=0;
            while 2^n<=i do
                n:=n+1;
            od;
            n:=n-1;
            r:=r+x^n;
            i:=i-2^n;
        od;
        return r;
    end;

The next function reverses this. to_ints takes a ring element and maps it to its corresponding integer. I do this by getting a list of the coefficients of the polynomial and for each nonzero coefficient, the result is increased by 2^n, in the same way that we would convert binary to decimal.

    to_ints:=function(r)
        local c,i,n;
        i:=0;n:=0;
        for c in CoefficientsOfUnivariatePolynomial(r) do
            if c=Z(2)^0 then          

                 # ^-- Right here you'll notice that the Z(2) is basically '1' in GF(2). So Z(2)^0 ~ 1 and Z(2)*0 ~ 0  
                 # effectively, this line checks for nonzero coefficients

                n:=n+2^i;
            fi;
            i:=i+1;
        od;
        return n;
    end;

For the final step, we call these functions. We take the two integer inputs, convert them into elements in the ring R, then multiply these elements together, and send the product back to the integers.

return to_ints( to_ring(i)*to_ring(j));

Ceylon, 90 bytes

alias I=>Integer;I x(I a,I b)=>[for(i in 0:64)if(b.get(i))a*2^i].fold(0)((y,z)=>y.xor(z));

This is just the algorithm as described: multiply a by 2^i wherever the ith bit is set in b, and add them all together using xor. Iterates over 0:64 because Integers are 64-bit in Ceylon when running on JVM (lower when running as Javascript, but then b.get(i) just returns false).

Formatted:

alias I => Integer;

I x(I a, I b) =>
      [
        for (i in 0:64)
            if (b.get(i))
                a * 2^i
      ].fold(0)((y, z) => y.xor(z));

The alias safes here just a single byte.

Julia, 35 33 30 bytes

f(a,b)=b%2*a$(b>0&&f(2a,b÷2))

This creates a recursive function f which takes two integers and returns the XOR product of the inputs.

Ungolfed:

function f(a, b)
    # Bitwise XOR : $
    # Short-circuit AND : &&

    b % 2 * a $ (b > 0 && f(2a, b ÷ 2))
end

Saved a couple bytes with encouragement from Sp3000!

Go, 63 bytes

func f(a,b uint)uint{if a<1{return 0};return a%2*b^f(a/2,b*2)}

Complete example:

http://play.golang.org/p/-ngNOnJGyM

Dart, 34 32 bytes

m(a,b)=>a<1?0:a%2*b^m(a~/2,b*2);

Straight-forward recursive implementation.

Mathematica, 40 bytes

BitXor@@(#2BitAnd[#,2^Range[0,Log2@#]])&

x86 machine code: 7 bytes

66 0F 3A 44 C1 00 C3  pclmulqdq xmm0, xmm1, 0 \ ret

Only two instructions. pclmulqdq does the heavy lifting, it literally implements that type of xor-multiplication. ret to make it a callable function, hopefully satisfying the requirement of "outputting" the result (in the return value, xmm0). Putting integer arguments in xmm args is a bit unusual, but I hope you'll forgive me.

Perl - 35 Bytes

#!perl -p
$\^=$`>>$_&1&&$'<<$_ for-/ /..31}{

Counting the command line option as one. Input is taken from STDIN, space separated.

Sample usage:

$ echo 13 11 | perl xormul.pl
127
$ echo 5 17 | perl xormul.pl
85
$ echo 14 13 | perl xormul.pl
70
$ echo 19 1 | perl xormul.pl
19
$ echo 63 63 | perl xormul.pl
1365

Z80, 11 bytes

B7 CB 32 30 01 B3 C8 CB 23 18 F6   

The code is called as a function. a and b are in D and E (the order doesn't matter) and the answer is stored in A when the code returns (there are no I/O functions).

B7      XOR A     //  A^=A (A=0)
CB 32   SRL D     //    CARRY = lsb(D), D>>=1, ZERO = D==0
30 01   JR NC, 1  //    jump 1 byte if not CARRY
B3      XOR E     //      A^=E, ZERO = A==0
C8      RET Z     //    return if ZERO
CB 23   SLA E     //    E<<=1
18 F6   JR -10    //    jump -10 bytes

It produces the correct results for all test input except 63@63 which returns 85 because all the registers are 8-bit and 1365 mod 256 = 85 (integer overflow).

Ruby, 76 75 73 bytes

a,b=$*.map{|x|x.to_i}
o=0
while(b>0)
o^=a&-(b&1)
a<<=1
b>>=1
end
puts(o)

Ruby, 60 bytes (function only, no I/O)

def t(a,b)
o=0
while(b>0)
o^=a&-(b&1)
a<<=1
b>>=1
end
t
end

Python 2, 35 bytes

f=lambda m,n:n and n%2*m^f(2*m,n/2)

Call like f(13, 14). I think most languages with a similar construct will converge on something like this.

C, 44 38 bytes

Thanks to nimi, we now use recursion for 6 fewer bytes!

f(a,b){return b?(b&1)*a^f(a*2,b/2):0;}

We define a function f which takes a, b.

This can be called like:

printf("%d @ %d = %d\n", 13, 14, f(13, 14));

Which outputs:

13 @ 14 = 70

Try the test cases online!

Haskell, 50 bytes

import Data.Bits
_#0=0
a#b=b.&.1*a`xor`2*a#div b 2

A translation of @BrainSteel's C answer. Usage example:

map (uncurry (#)) [(0,1),(1,2),(9,0),(6,1),(3,3),(2,5),(7,9),(13,11),(5,17),(14,13),(19,1),(63,63)]
[0,2,0,6,5,10,63,127,85,70,19,1365]

Python 2, 104 91 78 66 bytes

def y(a,b,c=0):
 for _ in bin(b)[:1:-1]:c^=int(_)*a;a<<=1
 print c

Take the bits of b in reverse order, ending before you hit the '0b' at the start of the string. Multiply each one by a and xor with the total, then left-shift a. Then print the total.

CJam, 14 13 bytes

q~2bf*{\2*^}*

How it works:

We first get the long multiplication results and then work our way up starting from the bottom two pairs.

q~                e# Eval the input. This puts the two numbers on stack
  2b              e# Convert the second number to binary
    f*            e# Multiply each bit of second number with the first number
                  e# This leaves an array with the candidates to be added in the long
                  e# multiplication step
      {    }*     e# Reduce on these candidates. Starting from the bottom
       \2*        e# Bit shift the lower candidate
          ^       e# XOR each other and continue

Try it online here

golflua 68

x,y=I.r("*n","*n")r=0~@i=0,31r=B.x(r,x*B.ls(B.rs(y,i)%2,i+1))$w(r/2)

Does basically the same bitshifting as Ypnypn's Java answer, but seems to require the divide by 2 at the end to work correctly. Takes in values as stdin, examples below

> 14 13 
70
> 19 1 
19
> 5 17 
85

Java, 62

(x,y)->{int r=0,i=0;for(;i<32;)r^=x*((y>>i)%2)<<i++;return r;}

Expanded

class XORMultiplication {
    public static void main(String[] args) {
        IntBinaryOperator f = (x, y) -> {
                    int r = 0, i = 0;
                    for (; i < 32;) {
                        r ^= x * ((y >> i) % 2) << i++;
                    }
                    return r;
                };
        System.out.println(f.applyAsInt(14, 13));
    }
}

J, 14 bytes

*/(~://.@)&.#:

Usage:

   5 (*/(~://.@)&.#:) 17     NB. enclosing brackets are optional
85

Explanation (reading mostly from right to left; u and v stand for arbitrary functions):

Try it online here.

Pyth, 13 12 bytes

uxyG*HQjvz2Z

Demonstration.

uxyG*HQjvz2Z
                  Implicit:
                  z = input()
                  Q = eval(input())
                  Z = 0

       jvz2       The first input, written in base 2, like so: [1, 0, 1, ...
u      jvz2Z      Reduce over the binary representation, starting with 0.
 x                XOR of
  yG              Twice the previous number
    *HQ           and the second input times the current bit.

Old version, 13 bytes:

xFm*vz.&Q^2dQ

Demonstration.