Skip to main content

Camouflage library, reversible data anonymization

Project description

Camouflage 🛡️

Python License Coverage Tests

Anonymize. Protect. Restore.
Flexible and reversible anonymization for modern Python workflows.


Ready to get started?

Install Camouflage with pip:

pip install camouflage

✨ What is Camouflage?

Camouflage lets you easily anonymize sensitive data, store reversible mappings, and restore the original dataset when needed — all while being fast, lightweight, and fully customizable.

  • 🔥 Anonymize large datasets quickly.
  • 🛠️ Add your own plugins easily (your data, your rules).
  • 🔄 Reversible by design — restore original values without headaches.
  • 🧪 100% test coverage for maximum trust.
  • 🏎️ Tested on datasets with over 100,000 rows across 6 columns — handles big data smoothly.

📈 How it Works

Camouflage uses a one-to-one mapping to anonymize data. It generates a unique, consistent, and reversible mapping for each value. See Bijection on Wikipedia.

Camouflage guarantees that every anonymized value is unique, consistent, and traceable back — only when you need it.


🚀 Quick Start

1️⃣ One-Time Anonymization

from camouflage import anonymize

original_value = "192.168.1.1"

anonymized_value = anonymize("ipv4", original_value)

2️⃣ Reversible Anonymization

from camouflage import anonymize, deanonymize, Transform

original_value = "192.168.1.1"

transform = Transform()

# Anonymize
anonymized_value = anonymize("ipv4", original_value, transform)

# Do something with the anonymized value
# ...

# De-anonymize
deanonymized_value = deanonymize("ipv4", anonymized_value, transform)

3️⃣ Anonymizing a Pandas DataFrame

import pandas as pd
from camouflage import PandasAdapter

df = pd.DataFrame({
    "ip": ["192.168.1.1", "10.0.0.1"],
    "joined_at": [pd.Timestamp("2023-01-01"), pd.Timestamp("2023-02-01")],
    "revenue": [1234.56, 7890.12],
})
# | ip          | joined_at           |   revenue |
# |:------------|:--------------------|----------:|
# | 192.168.1.1 | 2023-01-01 00:00:00 |   1234.56 |
# | 10.0.0.1    | 2023-02-01 00:00:00 |   7890.12 |

mapper = {
    "ip": "ipv4",
    "joined_at": "datetime",
    "revenue": "amount",
}

pd_adapter = PandasAdapter(mapper)

df_safe = pd_adapter.anonymize(df)
# | ip             | joined_at           |   revenue |
# |:---------------|:--------------------|----------:|
# | 137.224.91.30  | 2024-12-05 00:00:00 |   1279.97 |
# | 213.209.12.210 | 2023-06-27 00:00:00 |   5506.58 |

# Do something with the anonymized DataFrame
# ...

# When you want to restore:
original_df = pd_adapter.deanonymize(df_safe)
# | ip          | joined_at           |   revenue |
# |:------------|:--------------------|----------:|
# | 192.168.1.1 | 2023-01-01 00:00:00 |   1234.56 |
# | 10.0.0.1    | 2023-02-01 00:00:00 |   7890.12 |

🧩 Extending with Custom Anonymizers

Want to anonymize new types of data? Super easy:

1️⃣ Create your Custom Anonymizers

import random


def anonymize_color(_):  # It is crucial for the anonymizer to accept a single argument.
    return random.choice(['red', 'green', 'blue'])


def anonymize_red_channel(original_hex):
    hex_color = original_hex.lstrip('#')

    green = hex_color[2:4]
    blue = hex_color[4:6]

    random_red = random.randint(0, 255)

    return "#{:02X}{}{}".format(random_red, green, blue)

2️⃣ Register the Anonymizers

from camouflage import register_anonymizer

register_anonymizer('color', anonymize_color)
register_anonymizer('red_channel', anonymize_red_channel)

3️⃣ Use the Custom Anonymizers

from camouflage import anonymize

original_value = "cyan"
anonymized_value = anonymize("color", original_value)

original_hex = "#00FF00"
anonymized_hex = anonymize("red_channel", original_hex)

4️⃣ Or Use the Custom Anonymizers for Pandas

import pandas as pd
from camouflage import PandasAdapter

df = pd.DataFrame({
    "color": ["cyan", "magenta", "yellow"],
    "hex": ["#FF0000", "#00FF00", "#0000FF"],
})
# | color   | hex     |
# |:--------|:--------|
# | cyan    | #FF0000 |
# | magenta | #00FF00 |
# | yellow  | #0000FF |

mapper = {
    "color": "color",
    "hex": "red_channel",
}

pd_adapter = PandasAdapter(mapper)
df_safe = pd_adapter.anonymize(df)
# | color   | hex     |
# |:--------|:--------|
# | green   | #B90000 |
# | blue    | #96FF00 |
# | red     | #FD00FF |

✅ That's it — now you can anonymize columns as "color" or "red_channel" either one-time or in adapters!


✅ Quality You Can Trust

  • 100% code coverage (Pytest + Coverage)
  • PEP8 compliant, linted
  • Fast anonymization for datasets of 100,000+ rows
  • Extensible plugin system
  • Tested and battle-ready

🧪 Testing

Run tests on your setup with:

pip install pytest
pytest

📜 License

MIT License — do whatever you want, but be cool. ✌️


👨‍💻 Made with ❤️ by Developers, for Developers.

Camouflage is built to empower privacy-first applications without slowing you down.


🔗 Links

Source Code: https://github.com/NazarNintendo/camouflage
PyPI: https://pypi.org/project/camouflage/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

camouflage-1.0.2.tar.gz (12.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

camouflage-1.0.2-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

Details for the file camouflage-1.0.2.tar.gz.

File metadata

  • Download URL: camouflage-1.0.2.tar.gz
  • Upload date:
  • Size: 12.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.3

File hashes

Hashes for camouflage-1.0.2.tar.gz
Algorithm Hash digest
SHA256 f164ab179d9761840dcbe36b3df1a2209810f0641505f3550aa6dcbd1b4c52e0
MD5 26e6e15a3ccc34d36ffad851c883e474
BLAKE2b-256 32549c0f2ee44780dcb4b24f1f04a07b51013d4eab9f93be73bb56c65c97d61d

See more details on using hashes here.

File details

Details for the file camouflage-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: camouflage-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 11.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.3

File hashes

Hashes for camouflage-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0fc0de25876a11b0a93b2d03da2d436314fc675a5066094d439cee1e269c83e9
MD5 82faed11ee9ccb25dfbd27d05254d825
BLAKE2b-256 16878b60c6e8d0267cf0d22d2309806d411713e87ed2ae3ac7a3faaf0f8dc9ca

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page