Skip to content

Commit b0db9d9

Browse files
Create a patterned encoder
1 parent 3698907 commit b0db9d9

File tree

7 files changed

+156
-4
lines changed

7 files changed

+156
-4
lines changed

src/.idea/.idea.Stravaig.ShortCode/.idea/riderModule.iml

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using NUnit.Framework;
2+
3+
namespace Stravaig.ShortCode.Tests
4+
{
5+
[TestFixture]
6+
public class PatternedEncoderTests
7+
{
8+
[TestCase(1UL, ExpectedResult = "AA-00-ab")]
9+
[TestCase(27UL, ExpectedResult = "AA-00-bb")]
10+
[TestCase(675UL, ExpectedResult = "AA-00-zz")]
11+
[TestCase(676UL, ExpectedResult = "AA-01-aa")]
12+
[TestCase(677UL, ExpectedResult = "AA-01-ab")]
13+
[TestCase(6760UL, ExpectedResult = "AA-10-aa")]
14+
[TestCase(6761UL, ExpectedResult = "AA-10-ab")]
15+
[TestCase(67600UL, ExpectedResult = "AB-00-aa")]
16+
[TestCase(1757600UL, ExpectedResult = "BA-00-aa")]
17+
[TestCase(45697599UL, ExpectedResult = "ZZ-99-zz")]
18+
[TestCase(45697600UL, ExpectedResult = "AA-00-aa")]
19+
public string ConvertPattern(ulong code)
20+
{
21+
PatternedEncoder encoder = new PatternedEncoder(new[]
22+
{
23+
new PatternPart(NamedCharacterSpaces.UpperLatinLetters, 2),
24+
new PatternPart("-"),
25+
new PatternPart(NamedCharacterSpaces.Digits, 2),
26+
new PatternPart("-"),
27+
new PatternPart(NamedCharacterSpaces.LowerLatinLetters, 2),
28+
});
29+
30+
return encoder.Convert(code);
31+
}
32+
}
33+
}

src/Stravaig.ShortCode/Encoder.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Security.Cryptography.X509Certificates;
23

34
namespace Stravaig.ShortCode
45
{
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
namespace Stravaig.ShortCode
2+
{
3+
public class PatternPart
4+
{
5+
public string Pattern { get; set; }
6+
public PatternType Type { get; set; }
7+
public int Length { get; set; }
8+
9+
public PatternPart(string fixedChars)
10+
{
11+
Pattern = fixedChars;
12+
Type = PatternType.Fixed;
13+
Length = fixedChars.Length;
14+
}
15+
16+
public PatternPart(string characterSpace, int length)
17+
{
18+
Pattern = characterSpace;
19+
Type = PatternType.EncodeIntoCharacterSpace;
20+
Length = length;
21+
}
22+
}
23+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Stravaig.ShortCode
2+
{
3+
public enum PatternType
4+
{
5+
Fixed,
6+
EncodeIntoCharacterSpace,
7+
}
8+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace Stravaig.ShortCode
6+
{
7+
public class PatternedEncoder : IEncoder
8+
{
9+
private readonly PatternPart[] _parts;
10+
private readonly int _length;
11+
12+
public PatternedEncoder(IEnumerable<PatternPart> parts)
13+
{
14+
_parts = parts.ToArray();
15+
_length = _parts.Sum(p => p.Length);
16+
}
17+
18+
public string Convert(ulong fullCode, int? fixedChars = null, int maxChars = Int32.MaxValue)
19+
{
20+
if (fullCode == 0)
21+
throw new ArgumentOutOfRangeException(nameof(fullCode), $"Must be greater than zero.");
22+
23+
char[] result = new char[_length];
24+
ulong code = fullCode;
25+
int position = _length;
26+
for (int i = _parts.Length - 1; i >= 0; i--)
27+
{
28+
var part = _parts[i];
29+
position -= part.Length;
30+
code = BuildShortCode(code, part, result, position);
31+
}
32+
33+
return new string(result);
34+
}
35+
36+
private ulong BuildShortCode(ulong fullCode, PatternPart part, char[] code, int position)
37+
{
38+
if (part.Type == PatternType.Fixed)
39+
{
40+
for (int i = 0; i < part.Length; i++)
41+
code[position + i] = part.Pattern[i];
42+
return fullCode;
43+
}
44+
45+
ulong divisor = (ulong) part.Pattern.Length;
46+
for (int i = (position + part.Length - 1); i >= position; i--)
47+
{
48+
ulong remainder = fullCode % divisor;
49+
code[i] = part.Pattern[(int) remainder];
50+
fullCode = (fullCode - remainder) / divisor;
51+
}
52+
53+
return fullCode;
54+
}
55+
56+
public ulong RangeRequired(int numChars)
57+
{
58+
throw new NotImplementedException();
59+
}
60+
61+
public int MaxLength()
62+
{
63+
throw new NotImplementedException();
64+
}
65+
66+
public string NamedCharacterSpace =>
67+
throw new InvalidOperationException($"{nameof(NamedCharacterSpace)} is not applicable to this encoder.");
68+
69+
public string CharacterSpace =>
70+
throw new InvalidOperationException($"{nameof(CharacterSpace)} is not applicable to this encoding.");
71+
}
72+
}

src/Stravaig.ShortCode/ShortCode.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
using System;
2+
using System.Collections.Generic;
23

34
namespace Stravaig.ShortCode
45
{
56
public static class ShortCode
67
{
78
private static int _defaultLength;
89
private static Encoder _encoder;
10+
private static PatternedEncoder _patternedEncoder;
911
private static SequentialCodeGenerator _sequentialCodeGenerator;
1012
private static IShortCodeGenerator _randomGenerator;
1113

@@ -15,6 +17,14 @@ static ShortCode()
1517
_encoder = new Encoder(NamedCharacterSpaces.LettersAndDigits);
1618
_sequentialCodeGenerator = new SequentialCodeGenerator();
1719
_randomGenerator = new CryptographicallyRandomCodeGenerator();
20+
_patternedEncoder = new PatternedEncoder(new[]
21+
{
22+
new PatternPart(NamedCharacterSpaces.ReducedAmbiguity, 3),
23+
new PatternPart("-"),
24+
new PatternPart(NamedCharacterSpaces.ReducedAmbiguity, 3),
25+
new PatternPart("-"),
26+
new PatternPart(NamedCharacterSpaces.ReducedAmbiguity, 3),
27+
});
1828
}
1929

2030
public static string GenerateSequentialShortCode(int? length = null)
@@ -51,5 +61,10 @@ public static void SetDefaultLength(int length)
5161
{
5262
_randomGenerator = new TGenerator();
5363
}
64+
65+
public static void SetPattern(IEnumerable<PatternPart> patternParts)
66+
{
67+
_patternedEncoder = new PatternedEncoder(patternParts);
68+
}
5469
}
5570
}

0 commit comments

Comments
 (0)