45

I have two byte[] arrays which are of unknown length and I simply want to append one to the end of the other, i.e.:

byte[] ciphertext = blah;
byte[] mac = blah;
byte[] out = ciphertext + mac;

I have tried using arraycopy() but can't seem to get it to work.

Community
  • 1
  • 1
Mitch
  • 615
  • 2
  • 6
  • 6

6 Answers6

75

Using System.arraycopy(), something like the following should work:

// create a destination array that is the size of the two arrays
byte[] destination = new byte[ciphertext.length + mac.length];

// copy ciphertext into start of destination (from pos 0, copy ciphertext.length bytes)
System.arraycopy(ciphertext, 0, destination, 0, ciphertext.length);

// copy mac into end of destination (from pos ciphertext.length, copy mac.length bytes)
System.arraycopy(mac, 0, destination, ciphertext.length, mac.length);
jdknight
  • 1,801
  • 32
  • 52
krock
  • 28,904
  • 13
  • 79
  • 85
  • Excellent! Thanks for the quick solution. Works like a charm and seems so simple now! – Mitch Mar 20 '11 at 14:17
  • I believe it will create difficulties if we don't know the size of the final array in advance. – Shashwat Jun 06 '17 at 05:50
  • 1
    @Shashwat in this case, we already know the length of `ciphertext` and `mac` byte arrays. That means we know the length of the new byte array should be the combined length of the original 2 byte arrays. – krock Jul 12 '19 at 03:04
50

Perhaps the easiest way:

ByteArrayOutputStream output = new ByteArrayOutputStream();

output.write(ciphertext);
output.write(mac);

byte[] out = output.toByteArray();
Vadim
  • 635
  • 7
  • 9
20

You need to declare out as a byte array with a length equal to the lengths of ciphertext and mac added together, and then copy ciphertext over the beginning of out and mac over the end, using arraycopy.

byte[] concatenateByteArrays(byte[] a, byte[] b) {
    byte[] result = new byte[a.length + b.length]; 
    System.arraycopy(a, 0, result, 0, a.length); 
    System.arraycopy(b, 0, result, a.length, b.length); 
    return result;
} 
MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
9

The other provided solutions are great when you want to add only 2 byte arrays, but if you want to keep appending several byte[] chunks to make a single:

byte[] readBytes ; // Your byte array .... //for eg. readBytes = "TestBytes".getBytes();

ByteArrayBuffer mReadBuffer = new ByteArrayBuffer(0 ) ; // Instead of 0, if you know the count of expected number of bytes, nice to input here

mReadBuffer.append(readBytes, 0, readBytes.length); // this copies all bytes from readBytes byte array into mReadBuffer
// Any new entry of readBytes, you can just append here by repeating the same call.

// Finally, if you want the result into byte[] form:
byte[] result = mReadBuffer.buffer();
Khulja Sim Sim
  • 3,469
  • 1
  • 29
  • 28
7

First you need to allocate an array of the combined length, then use arraycopy to fill it from both sources.

byte[] ciphertext = blah;
byte[] mac = blah;
byte[] out = new byte[ciphertext.length + mac.length];


System.arraycopy(ciphertext, 0, out, 0, ciphertext.length);
System.arraycopy(mac, 0, out, ciphertext.length, mac.length);
rsp
  • 23,135
  • 6
  • 55
  • 69
4

I wrote the following procedure for concatenation of several array:

  static public byte[] concat(byte[]... bufs) {
    if (bufs.length == 0)
        return null;
    if (bufs.length == 1)
        return bufs[0];
    for (int i = 0; i < bufs.length - 1; i++) {
        byte[] res = Arrays.copyOf(bufs[i], bufs[i].length+bufs[i + 1].length);
        System.arraycopy(bufs[i + 1], 0, res, bufs[i].length, bufs[i + 1].length);
        bufs[i + 1] = res;
    }
    return bufs[bufs.length - 1];
}

It uses Arrays.copyOf

Singagirl
  • 465
  • 1
  • 3
  • 11