This repository provides a minimal example pipeline for processing Android device fingerprints collected with EXADPrinter.
It accompanies the paper:
EXADPrinter: Semi-Exhaustive Permissionless Device Fingerprinting Within the Android Ecosystem (PETS 2026)
The repository demonstrates how to:
- parse collected fingerprints
- clean and normalize attributes
- inspect the fingerprint structure
- run a small example data collection pipeline
To preserve user privacy, the repository does not contain the original datasets used in the paper, but includes dummy datasets that reproduce the expected data format.
If you use this artifact in your research, please cite:
@article{bouhenniche2026exadprinter,
author = {Bouhenniche Sihem, Laperdrix Pierre, Rudametkin Walter },
title = {EXADPrinter: Semi-Exhaustive Permissionless Device Fingerprinting Within the Android Ecosystem},
journal = {Proceedings on Privacy Enhancing Technologies},
year = {2026},
note = {To appear (PETS 2026)}
}
.
├── DUMMY_DATA/ # Browserstack devices fingerprints
├── DUMMY_DATA_PREPARED/ # Cleaned example fingerprints
├── DUMMY_DATA_STRUCTURE/ # Extracted fingerprint structure
├── fingerprint_parser/ # Python module for parsing attributes
├── data_cleaning_pipeline.ipynb # Notebook demonstrating cleaning pipeline
├── DataCollectionSetup/ # Example automation pipeline
└── requirements.txt # Python dependencies
Tested on:
- Ubuntu 20.04+
- Python 3.13
- pip
Install dependencies:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtThe repository provides a dummy dataset collected on real Android devices available through the BrowserStack platform. The dummy dataset contains 22 fingerprints collected from 11 devices, and is intended to:
- demonstrate the expected fingerprint format
- allow testing of the parsing and cleaning pipeline
Run the cleaning notebook:
jupyter notebook data_cleaning_pipeline.ipynbThe notebook will:
- load fingerprints from
DUMMY_DATA - parse attributes using
fingerprint_parser - apply cleaning rules
- generate processed fingerprints in:
DUMMY_DATA_PREPARED/
DUMMY_DATA_STRUCTURE/
This step is optional and not required to evaluate the artifact. The repository already contains dummy datasets that allow testing the full processing pipeline.
Instead of using the dummy dataset, you can run a small fingerprint collection experiment using the provided automation pipeline.
This example uses BrowserStack real Android devices. Official documentation for the BrowserStack App Automate service can be found here.
- Create BrowserStack account at https://www.browserstack.com/ (a free trial provides 100 minutes of Automate testing).
- You will need your BrowserStack credentials to run the automation pipeline.
- You can retrieve them from your account dashboard: https://www.browserstack.com/accounts/settings
- These values correspond to:
BROWSERSTACK_USERNAME
BROWSERSTACK_ACCESS_KEY
For more information, check the documentation: https://www.browserstack.com/docs/app-automate/appium/getting-started/python/pytest#configure-browserstack-credentials
Before running the automation, you must upload the EXADPrinter demo application.
- Upload the APK using the BrowserStack API as described here: https://www.browserstack.com/docs/app-automate/appium/set-up-test-env/upload-and-manage-apps
- After uploading the application, BrowserStack will return an app URL similar to:
bs://<app-id>
- This value should be used fo
APP_URLlater.
- Install
jqthen editDataCollectionSetup/pipeline.shby providing the following variables:
API_BASE_RL=
APP_URL=
BROWSERSTACK_USERNAME=
BROWSERSTACK_ACCESS_KEY=
Where:
API_BASE_URLis the server receiving fingerprints, if no API_BASE_URL is provided fingerprints will be sent to our servers.APP_URLis the URL of theexadprinterDemoApp.apkBROWSERSTACK_USERNAMEandBROWSERSTACK_ACCESS_KEYare your BrowserStack credentials
./pipeline.shThe script will:
- create BrowserStack sessions
- install the EXADPrinter demo application
- run fingerprint collection
- send fingerprints to your server. To do so, your must implement
<YOUR_SERVER_URL>/saveStructure/API endpoint and expect a POST request containing
- a fingerprint file (sent as
file) - a device identifier (sent as
uuid) The endpoint response should follow the schema below:
UploadResponse {
message: String
downloadUrl: String
fileName: String
}The list of devices used during the experiment is defined in capabilities.json. The file currently contains 3 device configurations. Additional devices can be added by following the BrowserStack capabilities documentation: https://www.browserstack.com/docs/app-automate/capabilities
This repository is part of the EXADPrinter artifact ecosystem.
https://github.com/AmIUniqueTools/AmIUniqueApp
Contains:
- the EXADPrinter Android library
- the AmIUnique Android application
The original dataset collected from real participants is not publicly available due to privacy and ethical considerations.
Instead, this repository includes:
- a small dummy dataset
- the full processing pipeline
- the complete data collection framework
This project is released under the license specified in the repository.