Skip to content

Commit a0e1efa

Browse files
feature/v2
- Added string extensions for substrings before/after. - Code improvements for hash parsing. - Added HMAC hash algorithm types.
1 parent 3788ec9 commit a0e1efa

File tree

12 files changed

+523
-28
lines changed

12 files changed

+523
-28
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// Copyright 2020-2021 ONIXLabs
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using Xunit;
16+
17+
namespace OnixLabs.Core.UnitTests
18+
{
19+
public sealed class StringExtensionTests
20+
{
21+
[Theory(DisplayName = "SubstringBefore should return the expected result (char)")]
22+
[InlineData("First:Second", "First", ':')]
23+
[InlineData("12345+678910", "12345", '+')]
24+
public void SubstringBeforeShouldReturnTheExpectedResultC(string value, string expected, char delimiter)
25+
{
26+
// Arrange / Act
27+
string actual = value.SubstringBefore(delimiter);
28+
29+
// Assert
30+
Assert.Equal(expected, actual);
31+
}
32+
33+
[Theory(DisplayName = "SubstringBefore should return the expected result (string)")]
34+
[InlineData("First:Second", "First", ":")]
35+
[InlineData("12345+678910", "12345", "+")]
36+
public void SubstringBeforeShouldReturnTheExpectedResultS(string value, string expected, string delimiter)
37+
{
38+
// Arrange / Act
39+
string actual = value.SubstringBefore(delimiter);
40+
41+
// Assert
42+
Assert.Equal(expected, actual);
43+
}
44+
45+
[Theory(DisplayName = "SubstringBeforeLast should return the expected result (char)")]
46+
[InlineData("First:Second:Third", "First:Second", ':')]
47+
[InlineData("12345+678910+12345", "12345+678910", '+')]
48+
public void SubstringBeforeLastShouldReturnTheExpectedResultC(string value, string expected, char delimiter)
49+
{
50+
// Arrange / Act
51+
string actual = value.SubstringBeforeLast(delimiter);
52+
53+
// Assert
54+
Assert.Equal(expected, actual);
55+
}
56+
57+
[Theory(DisplayName = "SubstringBeforeLast should return the expected result (string)")]
58+
[InlineData("First:Second:Third", "First:Second", ":")]
59+
[InlineData("12345+678910+12345", "12345+678910", "+")]
60+
public void SubstringBeforeLastShouldReturnTheExpectedResultS(string value, string expected, string delimiter)
61+
{
62+
// Arrange / Act
63+
string actual = value.SubstringBeforeLast(delimiter);
64+
65+
// Assert
66+
Assert.Equal(expected, actual);
67+
}
68+
69+
[Theory(DisplayName = "SubstringAfter should return the expected result (char)")]
70+
[InlineData("First:Second", "Second", ':')]
71+
[InlineData("12345+678910", "678910", '+')]
72+
public void SubstringAfterShouldReturnTheExpectedResultC(string value, string expected, char delimiter)
73+
{
74+
// Arrange / Act
75+
string actual = value.SubstringAfter(delimiter);
76+
77+
// Assert
78+
Assert.Equal(expected, actual);
79+
}
80+
81+
[Theory(DisplayName = "SubstringAfter should return the expected result (string)")]
82+
[InlineData("First:Second", "Second", ":")]
83+
[InlineData("12345+678910", "678910", "+")]
84+
public void SubstringAfterShouldReturnTheExpectedResultS(string value, string expected, string delimiter)
85+
{
86+
// Arrange / Act
87+
string actual = value.SubstringAfter(delimiter);
88+
89+
// Assert
90+
Assert.Equal(expected, actual);
91+
}
92+
93+
[Theory(DisplayName = "SubstringAfterLast should return the expected result (char)")]
94+
[InlineData("First:Second:Third", "Third", ':')]
95+
[InlineData("12345+678910+12345", "12345", '+')]
96+
public void SubstringAfterLastShouldReturnTheExpectedResultC(string value, string expected, char delimiter)
97+
{
98+
// Arrange / Act
99+
string actual = value.SubstringAfterLast(delimiter);
100+
101+
// Assert
102+
Assert.Equal(expected, actual);
103+
}
104+
105+
[Theory(DisplayName = "SubstringAfterLast should return the expected result (string)")]
106+
[InlineData("First:Second:Third", "Third", ":")]
107+
[InlineData("12345+678910+12345", "12345", "+")]
108+
public void SubstringAfterLastShouldReturnTheExpectedResultS(string value, string expected, string delimiter)
109+
{
110+
// Arrange / Act
111+
string actual = value.SubstringAfterLast(delimiter);
112+
113+
// Assert
114+
Assert.Equal(expected, actual);
115+
}
116+
}
117+
}

OnixLabs.Core/OnixLabs.Core.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@
1919
<DocumentationFile>bin\Debug\net5.0\OnixLabs.Core.xml</DocumentationFile>
2020
</PropertyGroup>
2121

22+
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
23+
<DocumentationFile>bin\Release\net5.0\OnixLabs.Core.xml</DocumentationFile>
24+
</PropertyGroup>
25+
2226
</Project>

OnixLabs.Core/StringExtensions.cs

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
// Copyright 2020-2021 ONIXLabs
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.ComponentModel;
17+
18+
namespace OnixLabs.Core
19+
{
20+
/// <summary>
21+
/// Provides extension methods for strings.
22+
/// </summary>
23+
[EditorBrowsable(EditorBrowsableState.Never)]
24+
public static class StringExtensions
25+
{
26+
/// <summary>
27+
/// The value of an index not found.
28+
/// </summary>
29+
private const int IndexNotFound = -1;
30+
31+
/// <summary>
32+
/// Returns a substring before the first occurrence of the specified delimiter.
33+
/// </summary>
34+
/// <param name="value">The original <see cref="string"/> from which to obtain a sub-string.</param>
35+
/// <param name="delimiter">The delimiter to find within the original string.</param>
36+
/// <param name="defaultValue">The value to return if the delimiter is not found, which defaults to the original string.</param>
37+
/// <returns>Returns a substring before the first occurrence of the specified delimiter.</returns>
38+
public static string SubstringBefore(
39+
this string value,
40+
char delimiter,
41+
string? defaultValue = null)
42+
{
43+
int index = value.IndexOf(delimiter);
44+
45+
return index switch
46+
{
47+
IndexNotFound => defaultValue ?? value,
48+
_ => value[..index]
49+
};
50+
}
51+
52+
/// <summary>
53+
/// Returns a substring before the first occurrence of the specified delimiter.
54+
/// </summary>
55+
/// <param name="value">The original <see cref="string"/> from which to obtain a sub-string.</param>
56+
/// <param name="delimiter">The delimiter to find within the original string.</param>
57+
/// <param name="defaultValue">The value to return if the delimiter is not found, which defaults to the original string.</param>
58+
/// <param name="comparison">Specifies the string comparison rule for the search.</param>
59+
/// <returns>Returns a substring before the first occurrence of the specified delimiter.</returns>
60+
public static string SubstringBefore(
61+
this string value,
62+
string delimiter,
63+
string? defaultValue = null,
64+
StringComparison comparison = StringComparison.Ordinal)
65+
{
66+
int index = value.IndexOf(delimiter, comparison);
67+
68+
return index switch
69+
{
70+
IndexNotFound => defaultValue ?? value,
71+
_ => value[..index]
72+
};
73+
}
74+
75+
/// <summary>
76+
/// Returns a substring before the last occurrence of the specified delimiter.
77+
/// </summary>
78+
/// <param name="value">The original <see cref="string"/> from which to obtain a sub-string.</param>
79+
/// <param name="delimiter">The delimiter to find within the original string.</param>
80+
/// <param name="defaultValue">The value to return if the delimiter is not found, which defaults to the original string.</param>
81+
/// <returns>Returns a substring before the last occurrence of the specified delimiter.</returns>
82+
public static string SubstringBeforeLast(
83+
this string value,
84+
char delimiter,
85+
string? defaultValue = null)
86+
{
87+
int index = value.LastIndexOf(delimiter);
88+
89+
return index switch
90+
{
91+
IndexNotFound => defaultValue ?? value,
92+
_ => value[..index]
93+
};
94+
}
95+
96+
/// <summary>
97+
/// Returns a substring before the last occurrence of the specified delimiter.
98+
/// </summary>
99+
/// <param name="value">The original <see cref="string"/> from which to obtain a sub-string.</param>
100+
/// <param name="delimiter">The delimiter to find within the original string.</param>
101+
/// <param name="defaultValue">The value to return if the delimiter is not found, which defaults to the original string.</param>
102+
/// <param name="comparison">Specifies the string comparison rule for the search.</param>
103+
/// <returns>Returns a substring before the last occurrence of the specified delimiter.</returns>
104+
public static string SubstringBeforeLast(
105+
this string value,
106+
string delimiter,
107+
string? defaultValue = null,
108+
StringComparison comparison = StringComparison.Ordinal)
109+
{
110+
int index = value.LastIndexOf(delimiter, comparison);
111+
112+
return index switch
113+
{
114+
IndexNotFound => defaultValue ?? value,
115+
_ => value[..index]
116+
};
117+
}
118+
119+
/// <summary>
120+
/// Returns a substring after the first occurrence of the specified delimiter.
121+
/// </summary>
122+
/// <param name="value">The original <see cref="string"/> from which to obtain a sub-string.</param>
123+
/// <param name="delimiter">The delimiter to find within the original string.</param>
124+
/// <param name="defaultValue">The value to return if the delimiter is not found, which defaults to the original string.</param>
125+
/// <returns>Returns a substring after the first occurrence of the specified delimiter.</returns>
126+
public static string SubstringAfter(
127+
this string value,
128+
char delimiter,
129+
string? defaultValue = null)
130+
{
131+
int index = value.IndexOf(delimiter);
132+
133+
return index switch
134+
{
135+
IndexNotFound => defaultValue ?? value,
136+
_ => value[(index + 1)..value.Length]
137+
};
138+
}
139+
140+
/// <summary>
141+
/// Returns a substring after the first occurrence of the specified delimiter.
142+
/// </summary>
143+
/// <param name="value">The original <see cref="string"/> from which to obtain a sub-string.</param>
144+
/// <param name="delimiter">The delimiter to find within the original string.</param>
145+
/// <param name="defaultValue">The value to return if the delimiter is not found, which defaults to the original string.</param>
146+
/// <param name="comparison">Specifies the string comparison rule for the search.</param>
147+
/// <returns>Returns a substring after the first occurrence of the specified delimiter.</returns>
148+
public static string SubstringAfter(
149+
this string value,
150+
string delimiter,
151+
string? defaultValue = null,
152+
StringComparison comparison = StringComparison.Ordinal)
153+
{
154+
int index = value.IndexOf(delimiter, comparison);
155+
156+
return index switch
157+
{
158+
IndexNotFound => defaultValue ?? value,
159+
_ => value[(index + delimiter.Length)..value.Length]
160+
};
161+
}
162+
163+
/// <summary>
164+
/// Returns a substring after the last occurrence of the specified delimiter.
165+
/// </summary>
166+
/// <param name="value">The original <see cref="string"/> from which to obtain a sub-string.</param>
167+
/// <param name="delimiter">The delimiter to find within the original string.</param>
168+
/// <param name="defaultValue">The value to return if the delimiter is not found, which defaults to the original string.</param>
169+
/// <returns>Returns a substring after the last occurrence of the specified delimiter.</returns>
170+
public static string SubstringAfterLast(
171+
this string value,
172+
char delimiter,
173+
string? defaultValue = null)
174+
{
175+
int index = value.LastIndexOf(delimiter);
176+
177+
return index switch
178+
{
179+
IndexNotFound => defaultValue ?? value,
180+
_ => value[(index + 1)..value.Length]
181+
};
182+
}
183+
184+
/// <summary>
185+
/// Returns a substring after the last occurrence of the specified delimiter.
186+
/// </summary>
187+
/// <param name="value">The original <see cref="string"/> from which to obtain a sub-string.</param>
188+
/// <param name="delimiter">The delimiter to find within the original string.</param>
189+
/// <param name="defaultValue">The value to return if the delimiter is not found, which defaults to the original string.</param>
190+
/// <param name="comparison">Specifies the string comparison rule for the search.</param>
191+
/// <returns>Returns a substring after the last occurrence of the specified delimiter.</returns>
192+
public static string SubstringAfterLast(
193+
this string value,
194+
string delimiter,
195+
string? defaultValue = null,
196+
StringComparison comparison = StringComparison.Ordinal)
197+
{
198+
int index = value.LastIndexOf(delimiter, comparison);
199+
200+
return index switch
201+
{
202+
IndexNotFound => defaultValue ?? value,
203+
_ => value[(index + delimiter.Length)..value.Length]
204+
};
205+
}
206+
}
207+
}

OnixLabs.Playground/OnixLabs.Playground.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
<ItemGroup>
1010
<ProjectReference Include="..\OnixLabs.Core\OnixLabs.Core.csproj" />
11+
<ProjectReference Include="..\OnixLabs.Security.Cryptography\OnixLabs.Security.Cryptography.csproj" />
1112
</ItemGroup>
1213

1314
</Project>

OnixLabs.Playground/Program.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,24 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
using System;
16+
using System.Security.Cryptography;
17+
using System.Text;
18+
using OnixLabs.Security.Cryptography;
19+
1520
namespace OnixLabs.Playground
1621
{
1722
internal static class Program
1823
{
1924
private static void Main(string[] args)
2025
{
26+
byte[] key = Encoding.ASCII.GetBytes("Test");
27+
byte[] data = Encoding.ASCII.GetBytes("Hello, World!");
28+
29+
using HMAC hmac = new HMACSHA256(key);
30+
byte[] result = hmac.ComputeHash(data);
31+
32+
Console.WriteLine(Hash.FromByteArray(result));
2133
}
2234
}
2335
}

0 commit comments

Comments
 (0)