{"id":18037706,"url":"https://github.com/tmthecoder/xotp","last_synced_at":"2025-03-27T09:31:57.815Z","repository":{"id":44690145,"uuid":"448208058","full_name":"tmthecoder/xotp","owner":"tmthecoder","description":"An HOTP \u0026 TOTP implementation in Rust","archived":false,"fork":false,"pushed_at":"2022-08-25T02:01:55.000Z","size":172,"stargazers_count":4,"open_issues_count":3,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-03-15T09:09:01.181Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/tmthecoder.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-15T07:14:16.000Z","updated_at":"2023-06-20T04:04:07.000Z","dependencies_parsed_at":"2022-08-31T11:13:54.023Z","dependency_job_id":null,"html_url":"https://github.com/tmthecoder/xotp","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmthecoder%2Fxotp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmthecoder%2Fxotp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmthecoder%2Fxotp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmthecoder%2Fxotp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tmthecoder","download_url":"https://codeload.github.com/tmthecoder/xotp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222226227,"owners_count":16951816,"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":[],"created_at":"2024-10-30T13:13:25.561Z","updated_at":"2024-10-30T13:13:26.202Z","avatar_url":"https://github.com/tmthecoder.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"## xotp\n\n[![crate](https://img.shields.io/crates/v/xotp.svg)](https://crates.io/crates/xotp)\n[![xotp](https://github.com/tmthecoder/xotp/actions/workflows/xotp.yml/badge.svg)](https://github.com/tmthecoder/xotp/actions/workflows/xotp.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA Rust implementation the [HOTP] and [TOTP] Algorithms.\n\n- HOTP was implemented in accordance with [RFC4226]\n- TOTP was implemented in accordance with [RFC6238]\n\n[RFC4226]: https://datatracker.ietf.org/doc/html/rfc4226\n[RFC6238]: https://datatracker.ietf.org/doc/html/rfc6238\n[HOTP]: https://en.wikipedia.org/wiki/HMAC-based_one-time_password\n[TOTP]: https://en.wikipedia.org/wiki/Time-based_One-Time_Password\n\n## Usage\n\nTo use HOTP:\n\n```rust\nuse xotp::hotp::HOTP;\n\nfn get_otp_with_hotp() {\n    let secret = \"secret\";\n    let counter = 0;\n    // Get a HOTP instance with a '\u0026str' secret\n    let hotp_str = HOTP::default_from_utf8(secret);\n    // Get an otp with the given counter\n    let otp_from_str = hotp_str.get_otp(counter);\n    println!(\"The otp from hotp_str: {}\", otp_from_str);\n\n    // Alternatively, get a HOTP instance with a '\u0026[u8]' secret\n    let hotp_bytes = HOTP::new(secret.as_bytes(), 6);\n    // Get an otp with the given counter\n    let otp_from_bytes = hotp_bytes.get_otp(counter);\n    println!(\"The otp from hotp_bytes: {}\", otp_from_bytes);\n}\n```\n\nTo use TOTP:\n\n```rust\nuse xotp::totp::TOTP;\nuse xotp::util::MacDigest; // Only needed if using a non-SHA1 hash function\nuse std::time::{Duration, SystemTime, UNIX_EPOCH};\n\nfn get_otp_with_totp() {\n    let secret = \"secret\";\n    let elapsed_seconds = SystemTime::now()\n        .duration_since(UNIX_EPOCH)\n        .expect(\"Error getting time\")\n        .as_secs();\n    // Get a TOTP instance with an '\u0026str' secret and default SHA1 Digest\n    let totp_sha1_str = TOTP::default_from_utf8(secret);\n    // Get an otp with the given counter and elapsed seconds\n    let otp_sha1 = totp_sha1_str.get_otp(elapsed_seconds);\n    println!(\"The otp from totp_sha1_str: {}\", otp_sha1);\n\n    // Alternatively get a TOTP instance with an '\u0026[u8]' secret\n    // and different digest (Sha256 or Sha512)\n    let totp_sha256_bytes = TOTP::new(\n        secret.as_bytes(),\n        MacDigest::SHA256, // SHA256 algorithm\n        8,  // 8 digits\n        60  // 60-second interval\n    );\n    // Get an otp with the given counter, time and other custom params\n    let otp_sha256 = totp_sha256_bytes.get_otp_with_custom_time_start(\n        elapsed_seconds,\n        0, // Start time at unix epoch\n    );\n    println!(\"The otp from totp_sha256_bytes: {}\", otp_sha256);\n}\n```\n\n## Changelog\n\nThe changelog for this crate can be found at [CHANGELOG.md](https://github.com/tmthecoder/xotp/blob/main/CHANGELOG.md)\n\n## Features and Bugs\n\nPlease file any featre requests or bug reports through the [issue tracker]\n\n[issue tracker]: https://github.com/tmthecoder/xotp/issues\n\n## Licensing\n\n- xotp is licensed under the [MIT License]\n\n[MIT License]: https://github.com/tmthecoder/xotp/blob/main/LICENSE\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftmthecoder%2Fxotp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftmthecoder%2Fxotp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftmthecoder%2Fxotp/lists"}