{"id":13871893,"url":"https://github.com/orchetect/SwiftRadix","last_synced_at":"2025-07-16T01:32:02.219Z","repository":{"id":41369754,"uuid":"136786606","full_name":"orchetect/SwiftRadix","owner":"orchetect","description":"Easily convert integers to binary/hex/octal strings and back again with clean functional syntax.","archived":false,"fork":false,"pushed_at":"2024-11-10T07:12:44.000Z","size":296,"stargazers_count":54,"open_issues_count":0,"forks_count":11,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-11-14T17:04:14.797Z","etag":null,"topics":["binary","generics","hex","hex-strings","hexadecimal","hexadecimal-string","integer","integers","ios","linux","macos","octal","radix","radix-strings","swift","swift5","tvos","watchos"],"latest_commit_sha":null,"homepage":"","language":"Swift","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/orchetect.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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,"publiccode":null,"codemeta":null},"funding":{"github":"orchetect"}},"created_at":"2018-06-10T06:55:27.000Z","updated_at":"2024-11-10T07:12:48.000Z","dependencies_parsed_at":"2024-06-25T04:48:20.852Z","dependency_job_id":"93028069-6e0b-4eae-b4b5-ba6f6bbe91f4","html_url":"https://github.com/orchetect/SwiftRadix","commit_stats":{"total_commits":86,"total_committers":4,"mean_commits":21.5,"dds":0.2674418604651163,"last_synced_commit":"9484e83a975811b37334933dd4b4d89abeb5e3bf"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orchetect%2FSwiftRadix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orchetect%2FSwiftRadix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orchetect%2FSwiftRadix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orchetect%2FSwiftRadix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/orchetect","download_url":"https://codeload.github.com/orchetect/SwiftRadix/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226089981,"owners_count":17572112,"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":["binary","generics","hex","hex-strings","hexadecimal","hexadecimal-string","integer","integers","ios","linux","macos","octal","radix","radix-strings","swift","swift5","tvos","watchos"],"created_at":"2024-08-05T23:00:29.661Z","updated_at":"2025-07-16T01:32:02.201Z","avatar_url":"https://github.com/orchetect.png","language":"Swift","readme":"![SwiftRadix](Images/swiftradix-banner.png)\n\n# SwiftRadix\n\n[![CI Build Status](https://github.com/orchetect/SwiftRadix/actions/workflows/build.yml/badge.svg)](https://github.com/orchetect/SwiftRadix/actions/workflows/build.yml) [![Platforms - macOS 10.10+ | iOS 9+ | tvOS 9+ | watchOS 2+ | visionOS 1+ | Linux](https://img.shields.io/badge/platforms-macOS%2010.10+%20|%20iOS%209+%20|%20tvOS%209+%20|%20watchOS%202+%20|%20visionOS%201+%20|%20Linux-lightgrey.svg?style=flat)](https://swiftpackageindex.com/orchetect/SwiftRadix/builds) [![License: MIT](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat)](https://github.com/orchetect/SwiftRadix/blob/main/LICENSE)\n\nA lightweight library useful for translating integers to and from radix strings (binary, hex, octal or any base) using simple, clean functional syntax.\n\nCompatible with all Apple platforms and Linux.\n\n## Summary\n\n### Common Usage\n\nUnified library with several constructor methods, all of which in turn provide all of the functionality of the library inline.\n\n| Option 1: Function | Option 2: Category method | Returns                                 |\n| ------------------ | ------------------------- | --------------------------------------- |\n| `Radix(T, base:)`  | `.radix(base:)`           | `Radix\u003cT\u003e(base: n)` where n is `2...36` |\n| `Binary(T)`        | `.binary`                 | `Radix\u003cT\u003e(base: 2)`                     |\n| `Octal(T)`         | `.octal`                  | `Radix\u003cT\u003e(base: 8)`                     |\n| `Hex(T)`           | `.hex`                    | `Radix\u003cT\u003e(base: 16)`                    |\n\nFor the sake of simplifying this documentation, `Hex()` / `.hex` will be used for most examples below.\n\n```swift\n// convert to or from hex strings\n\n255.hex.stringValue                                 // \"FF\"\n255.hex.stringValue(prefix: true)                   // \"0xFF\"\n255.hex.stringValue(prefix: true, uppercase: false) // \"0xff\"\n\"FF\".hex?.value                                     // Optional(255)\n\"0xFF\".hex?.value                                   // Optional(255)\n\"ZZ\".hex?.value                                     // nil (not valid hex string, so init fails)\n\n// work with arrays of any integer type, or hex strings and convert between them\n\n[0, 255, 0, 255].hex.stringValue                       // \"00 FF 00 FF\"\n[0, 255, 0, 255].hex.stringValues                      // [\"00\", \"FF\", \"00\", \"FF\"]\n[0, 255, 0, 255].hex.stringValue(prefixes: true)       // \"0x00 0xFF 0x00 0xFF\"\n[0, 255, 0, 255].hex.stringValues(prefixes: true)      // [\"0x00\", \"0xFF\", \"0x00\", \"0xFF\"]\n\n[0, 255, 0, 255].hex.stringValueArrayLiteral           // \"[0x0, 0xFF, 0x0, 0xFF]\"\n[0, 255, 0, 255].hex.stringValueArrayLiteral(padTo: 2) // \"[0x00, 0xFF, 0x00, 0xFF]\"\n\n[0, 65535, 4000].hex.stringValue                       // \"0 FFFF FA0\"\n[0, 65535, 4000].hex.stringValue(padTo: 2)             // \"00 FFFF FA0\"\n[0, 65535, 4000].hex.stringValue(padToEvery: 2)        // \"00 FFFF 0FA0\"\n[0, 65535, 4000].hex.stringValue(padToEvery: 4)        // \"0000 FFFF 0FA0\"\n\n[\"00\", \"FF\", \"ZZ\"].hex.values                          // [Optional(0), Optional(255), nil]\n\n// test for equatability or perform math operations with great flexibility,\n// without needing to extract the .value first, casting or converting\n\nUInt8(123).hex == Int16(123)      // true\n\"FF\".hex == 255                   // true\n\n123.hex + 10.binary - 10          // 123\n```\n\n## Installation\n\n### Swift Package Manager (SPM)\n\n1. Add SwiftRadix as a dependency using Swift Package Manager.\n\n   - In an app project or framework, in Xcode:\n\n     - Select the menu: **File → Swift Packages → Add Package Dependency...**\n     - Enter this URL: `https://github.com/orchetect/SwiftRadix`\n\n   - In a Swift Package, add it to the Package.swift dependencies:\n\n     ```swift\n     .package(url: \"https://github.com/orchetect/SwiftRadix\", from: \"1.3.0\")\n     ```\n\n### Cocoapods\n\n```bash\npod 'SwiftRadix'\n```\n\n## Documentation\n\n### Premise\n\nAt its core, a new generic type called `Radix` wraps any `BinaryInteger` value, as well as its associated base (radix).\n\n```swift\nRadix\u003cT: BinaryInteger\u003e\n\n// constructors\n\nRadix(0xFF, base: 16)                // Radix\u003cInt\u003e(255)?\nRadix(UInt8(0xFF), base: 16)         // Radix\u003cUInt8\u003e(255)?\nRadix\u003cUInt8\u003e(0xFF, base: 16)         // Radix\u003cUInt8\u003e(255)?\n\nRadix(0b1111, base: 2)               // Radix\u003cInt\u003e(15)?\n\n// category method to construct\n\n0xFF.radix(base: 16)                 // Radix\u003cInt\u003e(255)?\n0xFF.radix(base: 16, as: UInt8.self) // Radix\u003cUInt8\u003e(255)?\n```\n\nHowever, for common bases (binary base-2, octal base-8, hex base-16) you may never need to construct `Radix` directly. Instead, there are convenient functional category methods on common types and collections to shortcut these.\n\n```swift\n255.binary            // == Radix\u003cInt\u003e(0b11111111, base: 2)\n\"0b11111111\".binary   // == Radix\u003cInt\u003e(255, base: 2)?\n\n255.octal             // == Radix\u003cInt\u003e(0o377, base: 8)\n\"0o377\".octal         // == Radix\u003cInt\u003e(255, base: 8)?\n\n255.hex               // == Radix\u003cInt\u003e(0xFF, base: 16)\n\"0xFF\".hex            // == Radix\u003cInt\u003e(255, base: 16)?\n\n255.radix(base: 5)    // == Radix\u003cInt\u003e(255, base: 5)\n\"2010\".radix(base: 5) // == Radix\u003cInt\u003e(255, base: 5)?\n```\n\nYou will see how powerful and elegant these can be when combined, further down the README.\n\n### Proxy Constructors\n\nTwo invocation styles, producing the same result.\n\n```swift\n// proxy constructor function\nHex(123)                  // Radix\u003cInt\u003e(123, base: 16)\n\n// functional category property\n123.hex                   // Radix\u003cInt\u003e(123, base: 16)\n```\n\nAny `BinaryInteger` type can be used.\n\n```swift\nInt(123).hex              // Radix\u003cInt\u003e(123)\nInt8(123).hex             // Radix\u003cInt8\u003e(123)\nUInt8(123).hex            // Radix\u003cUInt8\u003e(123)\nInt16(123).hex            // Radix\u003cInt16\u003e(123)\nUInt16(123).hex           // Radix\u003cUInt16\u003e(123)\nInt32(123).hex            // Radix\u003cInt32\u003e(123)\nUInt32(123).hex           // Radix\u003cUInt32\u003e(123)\nInt64(123).hex            // Radix\u003cInt64\u003e(123)\nUInt64(123).hex           // Radix\u003cUInt64\u003e(123)\n```\n\nA valid hexadecimal string can be used, either containing the prefix `0x` or without it.\n\nThis constructor returns an `Optional`, since if the string is not valid hexadecimal, the constructor will fail and `nil` will be returned.\n\nIf no integer type is specified, the type will default to `Int`.\n\n```swift\nHex(\"FF\")                 // Radix\u003cInt\u003e(255)?\n\"FF\".hex                  // Radix\u003cInt\u003e(255)?\n\"0xFF\".hex                // Radix\u003cInt\u003e(255)?\n\n\"ZZZZ\".hex                // nil ; not a valid hex string\n```\n\nTo specify an integer type other than `Int`, specify it using `as:`.\n\n```swift\nHex(\"FF\", as: UInt8.self)      // Radix\u003cUInt8\u003e(255)?\n\"FF\".hex(as: UInt8.self)       // Radix\u003cUInt8\u003e(255)?\n\nHex(\"FFFFFF\", as: UInt8.self)  // nil -- 0xFFFFFF does not fit in UInt8, so init fails\n\"FFFFFF\".hex(as: UInt8.self)   // nil -- 0xFFFFFF does not fit in UInt8, so init fails\n```\n\n### Getting and Setting Values\n\nVarious methods become available:\n\n```swift\nlet h = 255.hex                               // Radix\u003cInt\u003e(255)\nh.value                                       // Int(255)\nh.stringValue                                 // \"FF\"\nh.stringValue(prefix: true)                   // \"0xFF\"\nh.stringValue(prefix: true, uppercase: false) // \"0xff\"\n\nh.stringValue = \"7F\"                          // can also set the hex String and get value...\nh.value                                       // 127, type Int\n```\n\nPadding to *n* number of leading zeros can be specified if you need uniform string formatting:\n\n```swift\n    0xF.hex.stringValue           // \"F\"\n    0xF.hex.stringValue(padTo: 2) // \"0F\"\n    0xF.hex.stringValue(padTo: 3) // \"00F\"\n\n 0xFFFF.hex.stringValue(padTo: 3) // \"FFFF\" - has no effect; it's \u003e 3 places\n```\n\nIt is also possible to pad leading zeros to every *n* multiple of digit places.\n\n```swift\n    0xF.hex.stringValue(padToEvery: 2) // \"0F\"\n   0xFF.hex.stringValue(padToEvery: 2) // \"FF\"\n  0xFFF.hex.stringValue(padToEvery: 2) // \"0FFF\"\n 0xFFFF.hex.stringValue(padToEvery: 2) // \"FFFF\"\n\n    0x1.hex.stringValue(padToEvery: 4) // \"0001\"\n0x12345.hex.stringValue(padToEvery: 4) // \"00012345\"\n```\n\nIn addition to padding, strings can be split every *n* digit places, and also in combination with padding.\n\n```swift\n    0xF.hex.stringValue(padTo: 8, splitEvery: 4)      // \"0000 000F\"\n0x123AB.hex.stringValue(padToEvery: 2, splitEvery: 2) // \"01 23 AB\"\n```\n\n### Equatability\n\n`Radix\u003cT\u003e` can be tested for equatability directly using typical operators (`==`, `!=`, `\u003e`, `\u003c`) without needing to access the `.value` property. This makes for cleaner, more convenient syntax.\n\n```swift\nlet h1 = 10.hex        // Radix\u003cInt\u003e\nlet h2 = 20.hex        // Radix\u003cInt\u003e\n\nh1.value == h2.value   // this works but it's easier to just do this...\nh1 == h2               // false\n```\n\nThey can be compared with great flexibility -- even between different integer types directly without requiring casting or conversions.\n\n```swift\nlet h1 = 10.hex        // Radix\u003cInt\u003e\nlet h2 = 20.hex        // Radix\u003cInt\u003e\nh1 == h2               // false  (comparing Radix\u003cInt\u003e with Radix\u003cInt\u003e)\nh1 \u003e 20                // true   (comparing Radix\u003cInt\u003e with Int)\nh1 != UInt8(20)        // true   (comparing Radix\u003cInt\u003e with UInt8)\n\n// even though \"FF\".hex produces an Optional,\n// the comparison still works safely without requiring the optional to be unwrapped first\n\"FF\".hex == 255        // true\n\"FF\".hex == 255.hex    // true\n\"ZZ\".hex == 255.hex    // false - optional is nil\n```\n\n### Additional Operators\n\nAdditional operators supported, allowing assignment and bitwise operations directly.\n\n- `+=`, `-=`, `*=`, `/=`, `\u003c\u003c`, `\u003e\u003e`, `\u0026`\n\n### Bitwise Shifting\n\nTraditional binary bit shift left/right is available directly on `Radix`.\n\n```swift\n0b0100.hex \u003c\u003c 1        // 0b1000\n0b0100.hex \u003e\u003e 1        // 0b0010\n```\n\n### Extensions on Array and Data\n\n#### [BinaryInteger]\n\nAny integer array can be converted to an equivalent `[Radix\u003cT\u003e]` Array:\n\n```swift\nlet a = [1, 2].hex           // [Radix\u003cInt\u003e(1), Radix\u003cInt\u003e(2)]\n\nlet arr: [UInt8] = [3, 4]\nlet b = arr.hex              // [Radix\u003cUInt8\u003e(3), Radix\u003cUInt8\u003e(4)]\n\n// and back again:\n\na.values                     // [1, 2] of type [Int]\nb.values                     // [3, 4] of type [UInt8]\n```\n\nIt can also be flattened into a concatenated `String` or an array of `String`s:\n```swift\n[0, 255, 0, 255].hex.stringValue                 // \"00 FF 00 FF\"\n[0, 255, 0, 255].hex.stringValue(prefix: true)   // \"0x00 0xFF 0x00 0xFF\"\n\n[0, 255, 0, 255].hex.stringValues                // [\"00\", \"FF\", \"00\", \"FF\"]\n[0, 255, 0, 255].hex.stringValues(prefix: true)  // [\"0x00\", \"0xFF\", \"0x00\", \"0xFF\"]\n```\n\n#### [String]\n\n`String` arrays can also be translated into an array of `Radix\u003cT\u003e?` . The `.values` property produces an unwrapped array of `[Optional\u003cT\u003e]`.\n\n```swift\n[\"00\", \"0xFF\", \"ZZ\"].hex.values   // [Optional(0), Optional(255), nil]\n```\n\nIt is also possible to easily generate a Swift source-compatible array literal.\n\n```swift\nlet arr = [0, 2, 255]\n\narr.hex.stringValueArrayLiteral    // \"[0x0, 0x2, 0xFF]\"\narr.binary.stringValueArrayLiteral // \"[0b0, 0b10, 0b11111111]\"\n```\n\n#### Data\n\nUseful when debugging binary data to the console, or presenting it in a human-readable format easily.\n\n```swift\nlet d = Data([0x1, 0x2, 0x3, 0xFF])\n\nd.hex.stringValue(padTo: 2)                          // \"01 02 03 FF\"\n```\n\n### Bits and Bytes Accessors\n\nA variety of additional methods for reading and manipulating the underlying integer value.\n\n#### Bit\n\nMethod: `.bit(Int)`\n\nSubscript: `[bit: Int] { get set }`\n\n- gets single bit value at specified position right-to-left\n- subscript can also be used to get or set bit values\n- radix-agnostic\n\n```swift\nvar h = 0b1100.binary\n\nh.bit(0)                  // 0b0.binary\nh.bit(2)                  // 0b1.binary\n\nh[bit: 0]                 // 0b0 (type T, which is Int in this case)\nh[bit: 2]                 // 0b1 (type T, which is Int in this case)\nh[bit: 2] = 0b0\nh.value                   // == 0b1000\n```\n\n#### Nibble\n\nMethod: `.nibble(Int)`\n\nSubscript: `[nibble: Int] { get set }`\n\n- gets nibble (4-bit) value at specified position right-to-left\n- subscript can also be used to get or set nibble values\n- radix-agnostic\n\n```swift\nvar h = 0x1234.hex\n\nh.nibble(0)               // 0x4.hex\nh.nibble(3)               // 0x1.hex\n\nh[nibble: 0]              // 0x4 (type T, which is Int in this case)\nh[nibble: 3]              // 0x1 (type T, which is Int in this case)\nh[nibble: 3] = 0xF\nh.value                   // == 0xF234\n```\n\n#### Bytes\n\n`.bytes`\n\n- A convenience property to return the raw bytes of the value as `[UInt8]` based on system endianness\n- radix-agnostic\n\n```swift\nlet bytes = 0xFF00.hex.bytes\n\nbytes // [0x00, 0xFF]\n```\n\n## Author\n\nCoded by a bunch of 🐹 hamsters in a trench coat that calls itself [@orchetect](https://github.com/orchetect).\n\n## License\n\nLicensed under the MIT license. See [LICENSE](LICENSE) for details.\n\n## Community \u0026 Support\n\nPlease do not email maintainers for technical support. Several options are available for issues and questions:\n\n- Questions and feature ideas can be posted to [Discussions](https://github.com/orchetect/SwiftRadix/discussions).\n- If an issue is a verifiable bug with reproducible steps it may be posted in [Issues](https://github.com/orchetect/SwiftRadix/issues).\n\n## Contributions\n\nContributions are welcome. Posting in [Discussions](https://github.com/orchetect/SwiftRadix/discussions) first prior to new submitting PRs for features or modifications is encouraged.\n","funding_links":["https://github.com/sponsors/orchetect"],"categories":["Swift"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forchetect%2FSwiftRadix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Forchetect%2FSwiftRadix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forchetect%2FSwiftRadix/lists"}