{"id":20985157,"url":"https://github.com/dlenski/python-motp","last_synced_at":"2025-05-14T17:31:40.207Z","repository":{"id":84077114,"uuid":"169165015","full_name":"dlenski/python-mOTP","owner":"dlenski","description":"Command-line client for generating Mobile-OTP / mOTP codes","archived":false,"fork":false,"pushed_at":"2019-06-26T18:47:58.000Z","size":3,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-04-03T08:10:16.957Z","etag":null,"topics":["authentication-token","mobile-otp","motp","otp","otp-generator"],"latest_commit_sha":null,"homepage":"http://motp.sourceforge.net","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dlenski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-02-04T23:20:02.000Z","updated_at":"2024-04-15T05:46:58.992Z","dependencies_parsed_at":null,"dependency_job_id":"4b62b52b-ac15-43d4-b494-03a2634fb44a","html_url":"https://github.com/dlenski/python-mOTP","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlenski%2Fpython-mOTP","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlenski%2Fpython-mOTP/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlenski%2Fpython-mOTP/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlenski%2Fpython-mOTP/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dlenski","download_url":"https://codeload.github.com/dlenski/python-mOTP/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254194860,"owners_count":22030435,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication-token","mobile-otp","motp","otp","otp-generator"],"created_at":"2024-11-19T05:55:34.869Z","updated_at":"2025-05-14T17:31:35.198Z","avatar_url":"https://github.com/dlenski.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nWhat is this for?\n=================\n\nIf you need to generate [one-time passwords](//en.wikipedia.org/wiki/One-time_password)\nusing the [Mobile-OTP / mOTP algorithm](http://motp.sourceforge.net/), from the command-line,\nwithout futzing around with your phone.\n\nThis is a self-proclaimed “standard” algorithm for one-time passwords. It is confusing,\nseemingly almost obsolete, and appears to mainly be used in German-speaking countries.\n**You don't want to use this unless you are forced to interact with an existing system\nthat uses such codes for 2FA.**\n\nMobile apps that appear to support it:\n\n* Swiss SafeLab OTP authenticator for iOS: [on iTunes](https://itunes.apple.com/us/app/otp-authenticator/id915359210?mt=8)\n* Swiss SafeLab OTP authenticator for Android: [APK download](https://www.swiss-safelab.com/en-us/products/otpauthenticator.aspx)\n* Android app that supports this algorithm: [DroidOTP on Google Play Store](https://play.google.com/store/apps/details?id=net.marinits.android.droidotp\u0026hl=de\u0026rdid=net.marinits.android.droidotp)\n\nHow does it work?\n=================\n\nThe principle of the algorithm is [explained badly](http://motp.sourceforge.net/#1.1)\nand [implemented confusingly](http://motp.sourceforge.net/bash/otpverify.sh) but it's very simple: you have a token secret\n(an ASCII string, usually hexadecimal or alphanumeric) and a PIN (an\nASCII string, usually 4 digits), and this is converted to a 6-digit\ncode using:\n\n```\ncounter = ASCII((UNIX epoch time) / 10s)\ndigest = MD5HEX(counter || secret || pin)\ncode = LEFT(digest, 6 characters)\n```\n\nThat's it. ¯\\\\\\_\\(ツ\\)\\_\\/¯\n\nUse it\n======\n\nRequires Python **3.x**.\n\n```\n$ ./motp.py SECRET PIN\na1b329\n```\n\nMore verbosely:\n\n```\n$ ./motp.py -v SECRET PIN\nEpoch time: 1549323786\nCounter:    154932378\n\na1b329 (current)\n```\n\nAll available options:\n\n```\n$ ./motp.py --help\nusage: motp.py [-h] [-s SECONDS] [-l LENGTH] [-w WINDOW] [-v] secret pin\n\npositional arguments:\n  secret                mOTP secret value (often hex or alphanumeric digits)\n  pin                   mOTP PIN value (usually 4 digits)\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -s SECONDS, --seconds SECONDS\n                        Duration of mOTP codes in seconds (default 30 seconds)\n  -l LENGTH, --length LENGTH\n                        Length of mOTP output (default 6 characters)\n  -w WINDOW, --window WINDOW\n                        Number of counter values before and after current one\n                        to show (for testing time-skew)\n  -v, --verbose\n```\n\nLicense\n=======\n\n[MIT](LICENSE.txt)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdlenski%2Fpython-motp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdlenski%2Fpython-motp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdlenski%2Fpython-motp/lists"}