diff --git a/duniterpy/documents/membership.py b/duniterpy/documents/membership.py
index 592858afcc84d1f26184f7d2c53df1a9f9d15033..86e4056b320ee5d8fab9eb7a2cc6fe6379c1b9b2 100644
--- a/duniterpy/documents/membership.py
+++ b/duniterpy/documents/membership.py
@@ -14,7 +14,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import re
-from typing import Type, TypeVar
+from typing import Any, Type, TypeVar
 
 from ..constants import (
     BLOCK_ID_REGEX,
@@ -105,6 +105,35 @@ class Membership(Document):
         if signing_key is not None:
             self.sign(signing_key)
 
+    def __eq__(self, other: Any) -> bool:
+        """
+        Check Membership instances equality
+        """
+        if not isinstance(other, Membership):
+            return NotImplemented
+        return (
+            super().__eq__(other)
+            and self.issuer == other.issuer
+            and self.membership_block_id == other.membership_block_id
+            and self.uid == other.uid
+            and self.identity_block_id == other.identity_block_id
+            and self.membership_type == other.membership_type
+        )
+
+    def __hash__(self) -> int:
+        return hash(
+            (
+                self.issuer,
+                self.membership_block_id,
+                self.uid,
+                self.identity_block_id,
+                self.membership_type,
+                self.version,
+                self.currency,
+                self.signature,
+            )
+        )
+
     @classmethod
     def from_inline(
         cls: Type[MembershipType],
diff --git a/tests/documents/test_membership.py b/tests/documents/test_membership.py
index edadb065914eeaea23f10bdec8c2eff555cddad4..bc49de15cd2b4a186a20eb1097c6f3e68c0dc280 100644
--- a/tests/documents/test_membership.py
+++ b/tests/documents/test_membership.py
@@ -15,6 +15,9 @@
 
 import unittest
 
+import pytest
+
+from duniterpy.constants import G1_TEST_CURRENCY_CODENAME
 from duniterpy.documents.membership import Membership
 
 membership_inline = "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:\
@@ -104,3 +107,33 @@ class TestMembership(unittest.TestCase):
             "dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu84rraDg==",
         )
         self.assertEqual(from_rendered_membership.membership_type, "IN")
+
+
+ISSUER = "issuer"
+MEMB_BLOCK_ID = "2-MEMB"
+UID = "uid"
+IDTY_BLOCK_ID = "0-IDTY"
+MEMBERSHIP_KWARGS = [ISSUER, MEMB_BLOCK_ID, UID, IDTY_BLOCK_ID]
+
+
+def test_membership_equality():
+    memb1 = Membership(*MEMBERSHIP_KWARGS)
+    memb2 = Membership(*MEMBERSHIP_KWARGS)
+    assert memb1 == memb2
+
+
+@pytest.mark.parametrize(
+    "issuer, memb_block_id, uid, idty_block_id, currency",
+    [
+        (ISSUER, MEMB_BLOCK_ID, "test", IDTY_BLOCK_ID, None),
+        (ISSUER, MEMB_BLOCK_ID, UID, "1-TEST", None),
+        ("test", MEMB_BLOCK_ID, UID, IDTY_BLOCK_ID, None),
+        MEMBERSHIP_KWARGS + [G1_TEST_CURRENCY_CODENAME],
+    ],
+)
+def test_membership_inequality(issuer, memb_block_id, uid, idty_block_id, currency):
+    memb1 = Membership(*MEMBERSHIP_KWARGS)
+    memb2 = Membership(issuer, memb_block_id, uid, idty_block_id)
+    if currency:
+        memb2.currency = currency
+    assert not memb1 == memb2