diff --git a/common/ByteArray.cpp b/common/ByteArray.cpp
index d54ab7adf9dd9def74799c6ae4c7d859b22d387f..7ae86d75b19074ac4be7e8154547af211da580e2 100644
--- a/common/ByteArray.cpp
+++ b/common/ByteArray.cpp
@@ -18,6 +18,8 @@
 
 #include "common/ByteArray.hpp"
 
+#include <ostream>
+
 //------------------------------------------------------------------------------
 // constructor
 //------------------------------------------------------------------------------
@@ -85,6 +87,34 @@ cta::ByteArray &cta::ByteArray::operator=(const ByteArray &rhs) {
   return *this;
 }
 
+//------------------------------------------------------------------------------
+// operator==
+//------------------------------------------------------------------------------
+bool cta::ByteArray::operator==(const ByteArray &rhs) const {
+  if(this == &rhs) {
+    return true;
+  }
+
+  if(m_size != rhs.m_size) {
+    return false;
+  }
+
+  for(uint32_t i = 0; i < m_size; i++) {
+    if(m_bytes[i] != rhs.m_bytes[i]) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+//------------------------------------------------------------------------------
+// operator!=
+//------------------------------------------------------------------------------
+bool cta::ByteArray::operator!=(const ByteArray &rhs) const {
+  return !operator==(rhs);
+}
+
 //------------------------------------------------------------------------------
 // getSize
 //------------------------------------------------------------------------------
@@ -98,3 +128,20 @@ uint32_t cta::ByteArray::getSize() const throw() {
 const uint8_t *cta::ByteArray::getBytes() const throw() {
   return m_bytes;
 }
+
+//------------------------------------------------------------------------------
+// operator<<
+//------------------------------------------------------------------------------
+std::ostream &operator<<(std::ostream &os, const cta::ByteArray &obj) {
+  os << "{";
+
+  const auto size = obj.getSize();
+  const auto bytes = obj.getBytes();
+
+  for(uint32_t i = 0; i < size; i++) {
+    os << bytes[i];
+  }
+
+  os << "}";
+  return os;
+}
diff --git a/common/ByteArray.hpp b/common/ByteArray.hpp
index 3d239248541752c625f89553e7a6a42ffc66d5f3..c297323a3c81dae7fb78d618e5171f139c3f8804 100644
--- a/common/ByteArray.hpp
+++ b/common/ByteArray.hpp
@@ -86,6 +86,22 @@ public:
    */
   ByteArray &operator=(const ByteArray &rhs);
 
+  /** 
+   * Returns true if the specified right-hand side is equal to this object.
+   *
+   * @param rhs The object on the right-hand side of the == operator.
+   * @return True if the specified right-hand side is equal to this object.
+   */
+  bool operator==(const ByteArray &rhs) const;
+
+  /**
+   * Returns true if the specified right-hand side is not euqal to this object.
+   *
+   * @param rhs The object on the right-hand side of the != operator.
+   * @return True if the specified right-hand side is not equal to this object.
+   */
+  bool operator!=(const ByteArray &rhs) const;
+
   /**
    * Returns the size of the array in bytes.
    *
@@ -101,7 +117,7 @@ public:
    * @return The contents of the array of bytes or NULL if the array is empty.
    */
   const uint8_t *getBytes() const throw();
-    
+
 private:
 
   /**
@@ -117,3 +133,8 @@ private:
 }; // class ByteArray
 
 } // namespace cta
+
+/**
+ * Output stream operator for the cta::ByteArray class.
+ */
+std::ostream &operator<<(std::ostream &os, const cta::ByteArray &obj);
diff --git a/common/ByteArrayTest.cpp b/common/ByteArrayTest.cpp
index c986bfceb7207ea1413e26ced6e5d394e92a76df..a5d63239f17ac5fe75945bc9a58312fac279834a 100644
--- a/common/ByteArrayTest.cpp
+++ b/common/ByteArrayTest.cpp
@@ -146,4 +146,64 @@ TEST_F(cta_ByteArrayTest, assignment_operator) {
   ASSERT_NE(byteArray1.getBytes(), byteArray2.getBytes());
 }
 
+TEST_F(cta_ByteArrayTest, equality_operator_eq) {
+  using namespace cta;
+
+  const uint32_t arraySize1 = 4;
+  const uint8_t bytes1[4] = {10, 20, 30, 40};
+  const ByteArray byteArray1(arraySize1, bytes1);
+
+  ASSERT_EQ(arraySize1, byteArray1.getSize());
+  ASSERT_EQ((uint8_t)10, byteArray1.getBytes()[0]);
+  ASSERT_EQ((uint8_t)20, byteArray1.getBytes()[1]);
+  ASSERT_EQ((uint8_t)30, byteArray1.getBytes()[2]);
+  ASSERT_EQ((uint8_t)40, byteArray1.getBytes()[3]);
+
+
+  const uint32_t arraySize2 = 4;
+  const uint8_t bytes2[4] = {10, 20, 30, 40};
+  ByteArray byteArray2(arraySize2, bytes2);
+
+  ASSERT_EQ(arraySize2, byteArray2.getSize());
+  ASSERT_EQ((uint8_t)10, byteArray2.getBytes()[0]);
+  ASSERT_EQ((uint8_t)20, byteArray2.getBytes()[1]);
+  ASSERT_EQ((uint8_t)30, byteArray2.getBytes()[2]);
+  ASSERT_EQ((uint8_t)40, byteArray2.getBytes()[3]);
+
+  ASSERT_EQ(byteArray1, byteArray2);
+}
+
+TEST_F(cta_ByteArrayTest, equality_operator_ne) {
+  using namespace cta;
+
+  const uint32_t arraySize1 = 4;
+  const uint8_t bytes1[4] = {10,20,30,40};
+  const ByteArray byteArray1(arraySize1, bytes1);
+
+  ASSERT_EQ(arraySize1, byteArray1.getSize());
+  ASSERT_EQ((uint8_t)10, byteArray1.getBytes()[0]);
+  ASSERT_EQ((uint8_t)20, byteArray1.getBytes()[1]);
+  ASSERT_EQ((uint8_t)30, byteArray1.getBytes()[2]);
+  ASSERT_EQ((uint8_t)40, byteArray1.getBytes()[3]);
+
+
+  const uint32_t arraySize2 = 10;
+  const uint8_t bytes2[10] = {10, 9, 8, 7 ,6 , 5, 4, 3, 2, 1};
+  ByteArray byteArray2(arraySize2, bytes2);
+
+  ASSERT_EQ(arraySize2, byteArray2.getSize());
+  ASSERT_EQ((uint8_t)10, byteArray2.getBytes()[0]);
+  ASSERT_EQ( (uint8_t)9, byteArray2.getBytes()[1]);
+  ASSERT_EQ( (uint8_t)8, byteArray2.getBytes()[2]);
+  ASSERT_EQ( (uint8_t)7, byteArray2.getBytes()[3]);
+  ASSERT_EQ( (uint8_t)6, byteArray2.getBytes()[4]);
+  ASSERT_EQ( (uint8_t)5, byteArray2.getBytes()[5]);
+  ASSERT_EQ( (uint8_t)4, byteArray2.getBytes()[6]);
+  ASSERT_EQ( (uint8_t)3, byteArray2.getBytes()[7]);
+  ASSERT_EQ( (uint8_t)2, byteArray2.getBytes()[8]);
+  ASSERT_EQ( (uint8_t)1, byteArray2.getBytes()[9]);
+
+  ASSERT_NE(byteArray1, byteArray2);
+}
+
 } // namespace unitTests