Skip to content

Commit 2c05920

Browse files
Merge pull request #135 from Stravaig-Projects/#129/yt-style
#129 Add You Tube style short codes
2 parents cfddc1f + b6c3050 commit 2c05920

File tree

10 files changed

+133
-7
lines changed

10 files changed

+133
-7
lines changed

.vscode/settings.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{
22
"restructuredtext.confPath": "",
33
"cSpell.words": [
4+
"commitish",
45
"Dependabot",
56
"Dependabots",
67
"Nuget",
7-
"Stravaig",
8-
"commitish",
98
"nupkg",
109
"pwsh",
11-
"snupkg"
10+
"Shouldly",
11+
"snupkg",
12+
"Stravaig"
1213
]
1314
}

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ There are some configuration methods you can call during your app's startup:
7070
- `RandomCodeGenerator`: The code is generated from the `Random` class.
7171
- `CryptographicallyRandomCodeGenerator`: The code is generated using a cryptographic strength random number generator.
7272

73+
Starting from v2, there is a configuration methods for specific configurations.
74+
75+
- `ShortCode.InitYouTubeStyle(bool)`: The short code is configured to generate short codes in the same style as You Tube, i.e. 11 character URL safe base64 without trailing equal signs.
76+
7377
## Setting up Short Codes with Microsoft's Dependency Injection
7478

7579
If web apps this will be in your `Startup` class, somewhere in the `ConfigureServices` method. Otherwise it will go wherever you are adding your dependency to the service collection.
@@ -94,6 +98,17 @@ The `options` are not required, and if missing a reasonable set of defaults will
9498

9599
Once set up, in your application code you need to add `IShortCodeFactory` to any class that needs to generate short codes.
96100

101+
### Configuring preset styles
102+
103+
Starting from Version 2, you can set up preset styles of short code.
104+
105+
e.g.
106+
```csharp
107+
services.AddYouTubeStyleShortCodeGenerator<GuidCodeGenerator>();
108+
```
109+
110+
This will set up the short code factory to generate codes that are like those used on You Tube, i.e. 11 character, base64 like without trailing equals signs.
111+
97112
### SequentialCodeGenerator
98113

99114
This generator takes additional options as it will reset to zero on each application run (which may not be desirable).

release-notes/wip-release-notes.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
Date: ???
66

7-
### Bugs
8-
97
### Features
108

9+
- #129: Add built in settings for You Tube style (11-char base64-like) short codes.
10+
1111
### Miscellaneous
1212

1313
- #127: Add support for .NET 8.0
1414
- #128: Drop support for .NET Core 3.1 and .NET 5.0. For these projects use v1.x.
1515

1616
### Dependencies
1717

18-
18+
- Updated SourceLink to 8.0.0

src/Example/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ static void Main()
1313
var config = BuildConfig();
1414

1515
ServiceCollection services = new ServiceCollection();
16-
services.AddShortCodeGenerator<SequentialCodeGenerator>(config);
16+
services.AddYouTubeStyleShortCodeGenerator<RandomCodeGenerator>();
17+
//services.AddShortCodeGenerator<SequentialCodeGenerator>(config);
1718

1819
ServiceProvider provider = services.BuildServiceProvider();
1920
var factory = provider.GetRequiredService<IShortCodeFactory>();

src/Stravaig.ShortCode.DependencyInjection/ServiceProviderExtensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ namespace Stravaig.ShortCode.DependencyInjection
77
{
88
public static class ServiceProviderExtensions
99
{
10+
public static IServiceCollection AddYouTubeStyleShortCodeGenerator<TGenerator>(
11+
this IServiceCollection services)
12+
where TGenerator : class, IShortCodeGenerator
13+
{
14+
return services.AddShortCodeGenerator<TGenerator>(opts => opts.SetYouTubeStyle());
15+
}
16+
1017
public static IServiceCollection AddShortCodeGenerator<TGenerator>(
1118
this IServiceCollection services,
1219
Action<ShortCodeOptions> options = null)

src/Stravaig.ShortCode.Tests/ShortCodeFactoryTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,23 @@ public void GetNextCode_ShouldReturnCode()
106106
Console.WriteLine(result);
107107
result.Length.ShouldBe(5);
108108
}
109+
110+
[Test]
111+
public void GetNextCode_WithYouTubeOptionsShouldYouTubeStyleCode()
112+
{
113+
var options = new ShortCodeOptions();
114+
options.SetYouTubeStyle();
115+
116+
var factory = new ShortCodeFactory(
117+
new GuidCodeGenerator(),
118+
new Encoder(NamedCharacterSpaces.ReducedAmbiguity),
119+
options,
120+
new NullLogger<ShortCodeFactory>());
121+
122+
var result = factory.GetNextCode();
123+
Console.WriteLine(result);
124+
result.Length.ShouldBe(11);
125+
}
109126

110127
[TestCase(1)]
111128
[TestCase(5)]

src/Stravaig.ShortCode.Tests/ShortCodeTests.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23
using NUnit.Framework;
34
using Shouldly;
@@ -33,6 +34,27 @@ public void DefaultSettings_HappyPath()
3334
randomCode2.Length.ShouldBe(7);
3435
randomCode1.ShouldNotBe(randomCode2);
3536
}
37+
38+
[Test]
39+
public void YouTubeStyleSettings_HappyPath()
40+
{
41+
ShortCode.InitYouTubeStyle(resetGenerators: true);
42+
43+
var sequentialCode1 = ShortCode.GenerateSequentialShortCode();
44+
sequentialCode1.Length.ShouldBe(11);
45+
sequentialCode1.ShouldBe("AAAAAAAAAAB");
46+
47+
var sequentialCode2 = ShortCode.GenerateSequentialShortCode();
48+
sequentialCode2.Length.ShouldBe(11);
49+
sequentialCode2.ShouldBe("AAAAAAAAAAC");
50+
51+
var randomCode1 = ShortCode.GenerateRandomShortCode();
52+
randomCode1.Length.ShouldBe(11);
53+
54+
var randomCode2 = ShortCode.GenerateRandomShortCode();
55+
randomCode2.Length.ShouldBe(11);
56+
randomCode1.ShouldNotBe(randomCode2);
57+
}
3658

3759
[Test]
3860
[TestCaseSource(sourceName: nameof(Lengths))]
@@ -103,6 +125,48 @@ public void Use_SetsTheInternalGeneratorToCryptographicallyRandom()
103125
generator.ShouldBeOfType(typeof(CryptographicallyRandomCodeGenerator));
104126
}
105127

128+
[Test]
129+
public void InitYouTubeStyle_ShouldSetupForYouTubeStyle()
130+
{
131+
// arrange
132+
dynamic shortCode = typeof(ShortCode).Jailbreak();
133+
var originalRandGenerator = (IShortCodeGenerator)shortCode._randomGenerator;
134+
var originalSeqGenerator = (IShortCodeGenerator)shortCode._sequentialCodeGenerator;
135+
136+
// Act
137+
ShortCode.InitYouTubeStyle();
138+
139+
// Assert
140+
((int)shortCode._defaultLength).ShouldBe(11);
141+
((IShortCodeGenerator)shortCode._randomGenerator).ShouldBe(originalRandGenerator);
142+
((IShortCodeGenerator)shortCode._sequentialCodeGenerator).ShouldBe(originalSeqGenerator);
143+
144+
dynamic encoder = ((Encoder)shortCode._encoder).Jailbreak();
145+
var characterSpace = (string)encoder._characterSpace;
146+
characterSpace.ShouldBe(NamedCharacterSpaces.UrlSafeBase64);
147+
}
148+
149+
[Test]
150+
public void InitYouTubeStyleWithReset_ShouldSetupForYouTubeStyle()
151+
{
152+
// arrange
153+
dynamic shortCode = typeof(ShortCode).Jailbreak();
154+
var originalRandGenerator = (IShortCodeGenerator)shortCode._randomGenerator;
155+
var originalSeqGenerator = (IShortCodeGenerator)shortCode._sequentialCodeGenerator;
156+
157+
// Act
158+
ShortCode.InitYouTubeStyle(resetGenerators: true);
159+
160+
// Assert
161+
((int)shortCode._defaultLength).ShouldBe(11);
162+
((IShortCodeGenerator)shortCode._randomGenerator).ShouldNotBe(originalRandGenerator);
163+
((IShortCodeGenerator)shortCode._sequentialCodeGenerator).ShouldNotBe(originalSeqGenerator);
164+
165+
dynamic encoder = ((Encoder)shortCode._encoder).Jailbreak();
166+
var characterSpace = (string)encoder._characterSpace;
167+
characterSpace.ShouldBe(NamedCharacterSpaces.UrlSafeBase64);
168+
}
169+
106170
private static IEnumerable<int> Lengths()
107171
{
108172
for (int i = 1; i <= 9; i++)

src/Stravaig.ShortCode/NamedCharacterSpaces.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public class NamedCharacterSpaces
1212
public const string LettersAndDigits = LatinLetters + Digits;
1313
public const string ReducedAmbiguity = "ABCDEFGHJKLMNPRTUVWXY2346789";
1414

15+
public const string UrlSafeBase64 = UpperLatinLetters + LowerLatinLetters + Digits + "-_";
16+
1517
public static readonly IReadOnlyDictionary<string, string> SpaceToName = new Dictionary<string, string>
1618
{
1719
{Digits, nameof(Digits)},
@@ -21,6 +23,7 @@ public class NamedCharacterSpaces
2123
{LatinLetters, nameof(LatinLetters)},
2224
{LettersAndDigits, nameof(LettersAndDigits)},
2325
{ReducedAmbiguity, nameof(ReducedAmbiguity)},
26+
{UrlSafeBase64, nameof(UrlSafeBase64)},
2427
};
2528
}
2629
}

src/Stravaig.ShortCode/ShortCode.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ private static void Init()
2121
_sequentialCodeGenerator = new SequentialCodeGenerator();
2222
_randomGenerator = new CryptographicallyRandomCodeGenerator();
2323
}
24+
25+
public static void InitYouTubeStyle(bool resetGenerators = false)
26+
{
27+
_defaultLength = 11;
28+
_encoder = new Encoder(NamedCharacterSpaces.UrlSafeBase64);
29+
if (resetGenerators)
30+
{
31+
_sequentialCodeGenerator = new SequentialCodeGenerator();
32+
_randomGenerator = new CryptographicallyRandomCodeGenerator();
33+
}
34+
}
2435

2536
public static string GenerateSequentialShortCode(int? length = null)
2637
{

src/Stravaig.ShortCode/ShortCodeOptions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,12 @@ public int? FixedLength
5757
}
5858

5959
public Dictionary<string, object> Generator { get; set; } = new Dictionary<string, object>();
60+
61+
public void SetYouTubeStyle()
62+
{
63+
CharacterSpace = NamedCharacterSpaces.UrlSafeBase64;
64+
MaxLength = 11;
65+
FixedLength = 11;
66+
}
6067
}
6168
}

0 commit comments

Comments
 (0)