{"id":26667306,"url":"https://github.com/sandersade/urlshortener","last_synced_at":"2025-06-17T01:03:03.715Z","repository":{"id":70126182,"uuid":"107262825","full_name":"SanderSade/UrlShortener","owner":"SanderSade","description":"Shorten IDs in URLs or convert between different mathematical bases","archived":false,"fork":false,"pushed_at":"2017-10-24T12:51:18.000Z","size":79,"stargazers_count":8,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-14T11:16:58.213Z","etag":null,"topics":["alphanumeric-id","base-conversion","csharp-library","netstandard20","url-shortener"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SanderSade.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2017-10-17T12:02:44.000Z","updated_at":"2024-01-09T23:04:23.000Z","dependencies_parsed_at":"2023-06-03T02:00:14.922Z","dependency_job_id":null,"html_url":"https://github.com/SanderSade/UrlShortener","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/SanderSade/UrlShortener","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SanderSade%2FUrlShortener","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SanderSade%2FUrlShortener/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SanderSade%2FUrlShortener/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SanderSade%2FUrlShortener/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SanderSade","download_url":"https://codeload.github.com/SanderSade/UrlShortener/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SanderSade%2FUrlShortener/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260269326,"owners_count":22983641,"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":["alphanumeric-id","base-conversion","csharp-library","netstandard20","url-shortener"],"created_at":"2025-03-25T19:36:56.904Z","updated_at":"2025-06-17T01:03:03.182Z","avatar_url":"https://github.com/SanderSade.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿[![GitHub license](https://img.shields.io/badge/licence-MPL%202.0-brightgreen.svg)](https://github.com/SanderSade/UrlShortener/blob/master/LICENSE)\n[![NetStandard 2.0](https://img.shields.io/badge/-.NET%20Standard%202.0-green.svg)](https://github.com/dotnet/standard/blob/master/docs/versions/netstandard2.0.md)\n[![NuGet v1.0.0](https://img.shields.io/badge/NuGet-v1.0.0-lightgrey.svg)](https://www.nuget.org/packages/SanderSade.UrlShortener/)\n\n## Introduction\n\nThe main purpose of the UrlShortener is to shorten in the URLs\n\nGreat many sites, such as [reddit](https://www.reddit.com), TinyUrl, bit.ly, goo.gl, t.co (Twitter) and Flickr, have a short alphanumeric ID (*[76pb94](https://www.reddit.com/r/programming/comments/76pb94/krack_attacks_breaking_wpa2/)*) instead of a long numeric value (*434521912*) in the URL. This makes the link shorter, easier for the user to see the differences in the URL - and it simply looks better, too.\n\nThere are two ways to achieve this. You can generate a string suitable for display and store it along with ID, or just store the numeric ID and convert the number to a string token and back. UrlShortener is intended to do the latter while giving more control to the developer than other similar libraries.\n\n\nIn addition, as a side-effect of the URL shortening functionality, UrlShortener can convert from **any positional [mathematical base](https://en.wikipedia.org/wiki/Radix) system to decimal and back**.\n\n\n##### Some examples\n\n**Full English alphanumeric (0..9, A..Z, a..z) - or base 62 - range:**\n* 9223372036854775807: AzL8n0Y58m7  \n* 934556467467656: 4HNODorwe   \n* 10622704081: Batman\n\n**Base 36 (0..9, a..z), like reddit uses:**\n* 434521912: 76pb94\n* 9223372036854775807: 1y2p0ij32e8e7\n\n**[Extended ASCII](https://en.wikipedia.org/wiki/Extended_ASCII) (base 256 - note that this is encoding-specific, and includes unprintable control characters!):**\n* 22077593942060647: Nothing\n* 7813499356810341497: Hello Dolly\n* 292756923184539821: \u0004\u0010\u0014ÞÛóh­  \n* 9223372036854775807: ÿÿÿÿÿÿÿ  \n\n\n**Unicode (using symbols ☔☕☀☂♣♠☁):** \n* 43: ☔☁☕  \n* 9223372036854775807: ☀☀☂♣☕☔☕☔☁☕☕☀♣♠☔♠☀☔♠☀☂☔☔ \n\n\n## Features\n\n* **Support for full Int64 range**  \nMany URL shortening libraries either support just Int32 values (which a popular website will use up in a few months - or less), or just positive numbers. UrlShortener supports full Int64 range, from -9223372036854775808 to 9223372036854775807.\n* **Full control of the used characters**  \nMost URL shortening libraries allow to use just a fixed set of characters - usually a..z, or 0..z. UrlShortener not only has multiple predefined common character sets, but also lets you to define any characters you want, in any order you want. You can do \"012345\" as your base or \"123qwe\" - both are properly handled as base 6. Or, for example, use the reversed decimal base, \"9876543210\".\n* **Includes common bases/character sets**  \nUrlShortener includes more than 20 of common character sets/bases, including base 36, base64url (RFC4648), multiple variants of base 62, RFC3986-compliant base 65, base 12 (Unicode and non-Unicode versions) and many more - see [CharacterSet.cs](https://github.com/SanderSade/UrlShortener/blob/master/UrlShortener/CharacterSet.cs).  \n* **Unicode support**  \nI really don't recommend the use of Unicode for URL shortening, but should you want to use [Internationalized Resource Identifiers](https://www.w3.org/International/articles/idn-and-iri/) ([RFC3987](https://tools.ietf.org/html/rfc3987)) or use base 12 Unicode version, UrlShortener supports Unicode characters.\n* **Input validation**  \nThere are some libraries that don't validate characters when converting to decimal. Depending on the algorithm used, this may return an invalid base-10 value without any errors. UrlShortener validates the input against your defined character set, and throws ApplicationException() if it contains invalid characters.   \n* **Fast**  \n  * Converting 10 000 000 decimal items (starting from int.MaxValue, or 2 147 483 647) to base 36 (0..9, a..z) took 00:00:05.9824399, or about 1.7M operations per second.\n  * Converting 10 000 000 base 36 items to decimal (using resulting values from previous test) took 00:00:05.1318302.  \nThe tests were done on a not-all-that-powerful laptop, and used sequential values, both of which affect the results - but they are a good indicator that performance really isn't something to worry about.  \n* **Sequence functionality**  \nYou can declare a starting decimal number in UrlShortener constructor (defaults to 0) and get sequential values in specified base calling `Next`. This is fully thread-safe, but the numbers are per UrlShortener instance (the library is intended to be used one-instance-per-base in your application/website).  \nThis should not be considered an alternative for database or other real sequence, but can be useful for unit or integration tests.  \nUrlShortener also has `Current` and `Previous` properties, latter moves the current to previous value, e.g. Current becomes Current - 1.\n* **.NET Standard 2.0**   \n[.NET Standard 2.0](https://github.com/dotnet/standard/blob/master/docs/versions/netstandard2.0.md) means this library can be used with .NET Framework 4.6.1+, .NET Core 2.0 and more - see [here](https://github.com/dotnet/standard/blob/master/docs/versions.md) for detailed information.\n\n### Help \u0026 examples\n\n\nAs said before, you should have just one instance per base in your application - e.g. initiate UrlShortener in your startup or first use, and store the instance in a static variable - or configure your dependency injection accordingly.\n\nA lot of examples can be found in the unit test project - [BaseConversionTests.cs](https://github.com/SanderSade/UrlShortener/blob/master/UrlShortener.Test/BaseConversionTests.cs).  \n\nDownload UrlShortener from [Releases](https://github.com/SanderSade/UrlShortener/releases) or fetch it via [NuGet](https://www.nuget.org/packages/SanderSade.UrlShortener/).\n\n* Simple conversion to base 62 (0..9, A..Z, a..z version), using .Convert() overloads:\n```\nvar urlShortener = new UrlShortener(CharacterSet.Base62NumbersUpperLower);\nvar decimalValue = urlShortener.Convert(\"fgzY7zdiN\");\nConsole.WriteLine(decimalValue); //9103348223453411: fgzY7zdiN\nConsole.WriteLine(decimalValue.DecimalValue); //9103348223453411\nvar baseValue = urlShortener.Convert(90909090);\nConsole.WriteLine(baseValue); //90909090: 69Rbe\nConsole.WriteLine(baseValue.BaseValue); //69Rbe\n```\n\n* Base 24 conversions:\n```\nvar urlShortener = new UrlShortener(24);\nConsole.WriteLine(urlShortener.FromInt64(986125456798543667)); //13014J3141FNFB\nConsole.WriteLine(urlShortener.ToInt64(\"1A2B3C4D5E6F\"));//2162225485250079\n``` \n\n* Binary conversion using custom symbols:\n```\nvar urlShortener = new UrlShortener(\"dT\");\nConsole.WriteLine(urlShortener.FromInt64(1398612542256797)); //TddTTTTTddddddddTTTTTdTTdTTTTddddTddTTTdTTdTddTTTdT\nConsole.WriteLine(urlShortener.ToInt64(\"ddTTdd\")); //12\n```\n\n* Next/Previous/Current functionality:\n```\nvar urlShortener = new UrlShortener(\"Uncopyrightable\", 1000); //longest word in English without repeating characters\nConsole.WriteLine(urlShortener.Current); //1000: prt\nConsole.WriteLine(urlShortener.Next); //1001: pra\nConsole.WriteLine(urlShortener.Current); //1001: pra\nConsole.WriteLine(urlShortener.Previous); //1000: prt\nConsole.WriteLine(urlShortener.Previous); //999: prh\nConsole.WriteLine(urlShortener.Current); //999: prh\n```\n\n### Changelog\n* 1.0 Initial release\n\n### Future plans \u0026 ideas\n* Think about switching from Int64 to BigInteger - this would allow converting GUID to other bases - but would use more resources.  \n* Add a simple MVC project demonstrating how to use the library\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandersade%2Furlshortener","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsandersade%2Furlshortener","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandersade%2Furlshortener/lists"}