Skip to content

Commit f30af77

Browse files
committed
Fix ndc encoding
1 parent e799854 commit f30af77

2 files changed

Lines changed: 20 additions & 10 deletions

File tree

src/FlexRender.Content.Ndc/NdcEncodings.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ internal static class NdcEncodings
1111
// QWERTY->JCUKEN mapping table (lowercase ASCII -> lowercase Cyrillic).
1212
// Source: Bfs.Integration.Ndc/Utils/NdcDisplayControls.RussianUppercaseLettersDict
1313
// Verified in production for years across multiple banks.
14-
// Uppercase is derived via char.ToUpper() on the mapped result.
14+
// Only lowercase Latin letters are mapped; uppercase Latin letters are preserved as-is
15+
// (they represent actual Latin characters in NDC data, not Cyrillic).
1516
private static readonly Dictionary<char, char> QwertyToJcukenMap = new()
1617
{
1718
['q'] = 'й', ['w'] = 'ц', ['e'] = 'у', ['r'] = 'к', ['t'] = 'е',
@@ -50,8 +51,7 @@ private static string DecodeQwertyJcuken(string text, bool uppercase)
5051
var needsMapping = false;
5152
foreach (var ch in text)
5253
{
53-
if (QwertyToJcukenMap.ContainsKey(ch) ||
54-
(char.IsAsciiLetterUpper(ch) && QwertyToJcukenMap.ContainsKey(char.ToLower(ch, CultureInfo.InvariantCulture))))
54+
if (QwertyToJcukenMap.ContainsKey(ch))
5555
{
5656
needsMapping = true;
5757
break;
@@ -70,18 +70,13 @@ private static string DecodeQwertyJcuken(string text, bool uppercase)
7070
var sb = new StringBuilder(text.Length);
7171
foreach (var ch in text)
7272
{
73-
// Try lowercase key first
7473
if (QwertyToJcukenMap.TryGetValue(ch, out var mapped))
7574
{
7675
sb.Append(uppercase ? char.ToUpper(mapped, CultureInfo.InvariantCulture) : mapped);
7776
}
78-
// Try converting uppercase ASCII to lowercase for lookup
79-
else if (char.IsAsciiLetterUpper(ch) && QwertyToJcukenMap.TryGetValue(char.ToLower(ch, CultureInfo.InvariantCulture), out var mappedFromUpper))
80-
{
81-
sb.Append(uppercase ? char.ToUpper(mappedFromUpper, CultureInfo.InvariantCulture) : mappedFromUpper);
82-
}
8377
else
8478
{
79+
// Uppercase Latin letters and all non-mapped chars preserved as-is
8580
sb.Append(uppercase ? char.ToUpper(ch, CultureInfo.InvariantCulture) : ch);
8681
}
8782
}

tests/FlexRender.Tests/Content/Ndc/NdcEncodingsTests.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,25 @@ public void QwertyJcuken_UppercaseFlag_ConvertsToUppercase()
4444
[Fact]
4545
public void QwertyJcuken_WithoutUppercase_AllLowercase()
4646
{
47-
// Without uppercase flag, uppercase ASCII keys still map to lowercase Cyrillic
4847
Assert.Equal("банк", NdcEncodings.Decode("~fyr", "qwerty-jcuken"));
4948
}
5049

50+
[Fact]
51+
public void QwertyJcuken_UppercaseLatinPreserved()
52+
{
53+
// Uppercase Latin letters are NOT converted — they represent actual Latin chars in NDC data
54+
Assert.Equal("A", NdcEncodings.Decode("A", "qwerty-jcuken"));
55+
Assert.Equal("TEST", NdcEncodings.Decode("TEST", "qwerty-jcuken"));
56+
Assert.Equal("Aбанк", NdcEncodings.Decode("A~fyr", "qwerty-jcuken"));
57+
}
58+
59+
[Fact]
60+
public void QwertyJcuken_UppercaseFlag_PreservesUppercaseLatin()
61+
{
62+
// With uppercase=true, uppercase Latin stays as-is, mapped chars become uppercase Cyrillic
63+
Assert.Equal("AБАНК", NdcEncodings.Decode("A~fyr", "qwerty-jcuken", uppercase: true));
64+
}
65+
5166
[Fact]
5267
public void QwertyJcuken_PreservesNonMappedChars()
5368
{

0 commit comments

Comments
 (0)