barcode object with (half of a skeleton) framework for parsing input

This commit is contained in:
Lynne Megido 2020-10-14 02:03:20 +10:00
parent b86f58c39f
commit 71590dc93d
Signed by: lynnesbian
GPG Key ID: F0A184B5213D9F90
7 changed files with 387 additions and 56 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
bin/ bin/
obj/ obj/
out/ out/
spec.*

View File

@ -15,6 +15,7 @@
<e p=".git/info/exclude" t="IncludeRecursive" /> <e p=".git/info/exclude" t="IncludeRecursive" />
<e p=".gitignore" t="Include" /> <e p=".gitignore" t="Include" />
<e p="Barcode.cs" t="Include" /> <e p="Barcode.cs" t="Include" />
<e p="BaseConversion.cs" t="Include" />
<e p="LICENSE" t="Include" /> <e p="LICENSE" t="Include" />
<e p="Program.cs" t="Include" /> <e p="Program.cs" t="Include" />
<e p="auspostcode.csproj" t="IncludeRecursive" /> <e p="auspostcode.csproj" t="IncludeRecursive" />

View File

@ -3,33 +3,71 @@
<component name="AutoGeneratedRunConfigurationManager"> <component name="AutoGeneratedRunConfigurationManager">
<projectFile>auspostcode.csproj</projectFile> <projectFile>auspostcode.csproj</projectFile>
</component> </component>
<component name="BranchesTreeState">
<expand>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="LOCAL_ROOT" type="e8cecc67:BranchNodeDescriptor" />
</path>
</expand>
<select>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="LOCAL_ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="BRANCH:master" type="e8cecc67:BranchNodeDescriptor" />
</path>
</select>
</component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="373c5ee6-3f10-450b-8af6-fc4dd99290b0" name="Default Changelist" comment="" /> <list default="true" id="373c5ee6-3f10-450b-8af6-fc4dd99290b0" name="Default Changelist" comment="initial commit, as they say">
<change afterPath="$PROJECT_DIR$/BaseConversion.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.auspostcode.dir/.idea/contentModel.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.auspostcode.dir/.idea/contentModel.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.auspostcode.dir/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.auspostcode.dir/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Barcode.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Barcode.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Folder.DotSettings.user" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Program.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Program.cs" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" /> <option name="LAST_RESOLUTION" value="IGNORE" />
</component> </component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="HighlightingSettingsPerFile">
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/87DBB896-6B20-4A14-9B6A-7AB43642646D/42/0e5622b9/Number.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/A5F6779E-8C83-415E-AF7A-DAB44F32C608/c6/1054d372/ThrowHelper.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/A5F6779E-8C83-415E-AF7A-DAB44F32C608/84/0eb89c24/Enumerable.cs" root0="SKIP_HIGHLIGHTING" />
</component>
<component name="IdeDocumentHistory"> <component name="IdeDocumentHistory">
<option name="CHANGED_PATHS"> <option name="CHANGED_PATHS">
<list> <list>
<option value="$PROJECT_DIR$/BarcodeVersion.cs" /> <option value="$PROJECT_DIR$/BarcodeVersion.cs" />
<option value="$PROJECT_DIR$/Barcode.cs" />
<option value="$PROJECT_DIR$/.gitignore" /> <option value="$PROJECT_DIR$/.gitignore" />
<option value="$PROJECT_DIR$/BaseConversion.cs" />
<option value="$PROJECT_DIR$/Program.cs" /> <option value="$PROJECT_DIR$/Program.cs" />
<option value="$PROJECT_DIR$/Barcode.cs" />
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectId" id="1ipA0w6VF4fF6sTNaNbeXBIkCaA" /> <component name="ProjectId" id="1ipA0w6VF4fF6sTNaNbeXBIkCaA" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState"> <component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
<property name="ASKED_SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
<property name="DebuggerViewTab_PTCS_FirstProportionKey" value="0.34975636" />
<property name="DebuggerViewTab_PTCS_LastProportionKey" value="0.29994586" />
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" /> <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" /> <property name="WebServerToolWindowFactoryState" value="false" />
<property name="XThreadsFramesViewSplitterKey" value="0.7161862" />
<property name="add_unversioned_files" value="true" /> <property name="add_unversioned_files" value="true" />
<property name="settings.editor.selected.configurable" value="preferences.pluginManager" /> <property name="settings.editor.selected.configurable" value="preferences.sourceCode.C#" />
<property name="vue.rearranger.settings.migration" value="true" /> <property name="vue.rearranger.settings.migration" value="true" />
</component> </component>
<component name="RunManager"> <component name="RunManager">
@ -60,36 +98,161 @@
<option name="number" value="Default" /> <option name="number" value="Default" />
<option name="presentableId" value="Default" /> <option name="presentableId" value="Default" />
<updated>1602593942454</updated> <updated>1602593942454</updated>
<workItem from="1602593947835" duration="3083000" /> <workItem from="1602593947835" duration="11001000" />
</task> </task>
<task id="LOCAL-00001" summary="initial commit, as they say">
<created>1602597326777</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1602597326778</updated>
</task>
<option name="localTasksCounter" value="2" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" /> <option name="version" value="3" />
</component> </component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State>
<option name="FILTERS">
<map>
<entry key="branch">
<value>
<list>
<option value="master" />
</list>
</value>
</entry>
</map>
</option>
</State>
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration"> <component name="VcsManagerConfiguration">
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" /> <option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
<MESSAGE value="initial commit, as they say" />
<option name="LAST_COMMIT_MESSAGE" value="initial commit, as they say" />
</component> </component>
<component name="WindowStateProjectService"> <component name="WindowStateProjectService">
<state x="747" y="114" width="600" height="702" key="#C#" timestamp="1602594041255"> <state x="747" y="114" width="600" height="702" key="#C#" timestamp="1602594041255">
<screen x="0" y="0" width="1920" height="1054" /> <screen x="0" y="0" width="1920" height="1054" />
</state> </state>
<state x="747" y="114" width="600" height="702" key="#C#/0.0.1920.1054@0.0.1920.1054" timestamp="1602594041255" /> <state x="747" y="114" width="600" height="702" key="#C#/0.0.1920.1054@0.0.1920.1054" timestamp="1602594041255" />
<state x="727" y="366" width="424" height="478" key="FileChooserDialogImpl" timestamp="1602594669824"> <state x="727" y="366" width="424" height="478" key="FileChooserDialogImpl" timestamp="1602597073977">
<screen x="0" y="0" width="1920" height="1054" /> <screen x="0" y="0" width="1920" height="1054" />
</state> </state>
<state x="727" y="366" width="424" height="478" key="FileChooserDialogImpl/0.0.1920.1054@0.0.1920.1054" timestamp="1602594669824" /> <state x="727" y="366" width="424" height="478" key="FileChooserDialogImpl/0.0.1920.1054@0.0.1920.1054" timestamp="1602597073977" />
<state x="449" y="161" key="SettingsEditor" timestamp="1602597031614"> <state width="1878" height="374" key="GridCell.Tab.0.bottom" timestamp="1602604911216">
<screen x="0" y="0" width="1920" height="1054" /> <screen x="0" y="0" width="1920" height="1054" />
</state> </state>
<state x="449" y="161" key="SettingsEditor/0.0.1920.1054@0.0.1920.1054" timestamp="1602597031614" /> <state width="1878" height="374" key="GridCell.Tab.0.bottom/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911216" />
<state x="440" y="285" width="1009" height="647" key="org.intellij.images.editor.actions.BackgroundImageDialog" timestamp="1602594711073"> <state width="1878" height="374" key="GridCell.Tab.0.center" timestamp="1602604911213">
<screen x="0" y="0" width="1920" height="1054" /> <screen x="0" y="0" width="1920" height="1054" />
</state> </state>
<state x="440" y="285" width="1009" height="647" key="org.intellij.images.editor.actions.BackgroundImageDialog/0.0.1920.1054@0.0.1920.1054" timestamp="1602594711073" /> <state width="1878" height="374" key="GridCell.Tab.0.center/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911213" />
<state x="623" y="231" width="672" height="678" key="search.everywhere.popup" timestamp="1602595553496"> <state width="1878" height="374" key="GridCell.Tab.0.left" timestamp="1602604911211">
<screen x="0" y="0" width="1920" height="1054" /> <screen x="0" y="0" width="1920" height="1054" />
</state> </state>
<state x="623" y="231" width="672" height="678" key="search.everywhere.popup/0.0.1920.1054@0.0.1920.1054" timestamp="1602595553496" /> <state width="1878" height="374" key="GridCell.Tab.0.left/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911211" />
<state width="1878" height="374" key="GridCell.Tab.0.right" timestamp="1602604911214">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.0.right/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911214" />
<state width="1878" height="374" key="GridCell.Tab.1.bottom" timestamp="1602604911221">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.1.bottom/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911221" />
<state width="1878" height="374" key="GridCell.Tab.1.center" timestamp="1602604911218">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.1.center/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911218" />
<state width="1878" height="374" key="GridCell.Tab.1.left" timestamp="1602604911217">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.1.left/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911217" />
<state width="1878" height="374" key="GridCell.Tab.1.right" timestamp="1602604911220">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.1.right/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911220" />
<state width="1878" height="374" key="GridCell.Tab.2.bottom" timestamp="1602604911227">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.2.bottom/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911227" />
<state width="1878" height="374" key="GridCell.Tab.2.center" timestamp="1602604911224">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.2.center/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911224" />
<state width="1878" height="374" key="GridCell.Tab.2.left" timestamp="1602604911223">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.2.left/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911223" />
<state width="1878" height="374" key="GridCell.Tab.2.right" timestamp="1602604911225">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.2.right/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911225" />
<state width="1878" height="374" key="GridCell.Tab.3.bottom" timestamp="1602604911232">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.3.bottom/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911232" />
<state width="1878" height="374" key="GridCell.Tab.3.center" timestamp="1602604911230">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.3.center/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911230" />
<state width="1878" height="374" key="GridCell.Tab.3.left" timestamp="1602604911229">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.3.left/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911229" />
<state width="1878" height="374" key="GridCell.Tab.3.right" timestamp="1602604911231">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.3.right/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911231" />
<state width="1878" height="374" key="GridCell.Tab.4.bottom" timestamp="1602604911236">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.4.bottom/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911236" />
<state width="1878" height="374" key="GridCell.Tab.4.center" timestamp="1602604911234">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.4.center/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911234" />
<state width="1878" height="374" key="GridCell.Tab.4.left" timestamp="1602604911233">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.4.left/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911233" />
<state width="1878" height="374" key="GridCell.Tab.4.right" timestamp="1602604911235">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state width="1878" height="374" key="GridCell.Tab.4.right/0.0.1920.1054@0.0.1920.1054" timestamp="1602604911235" />
<state x="738" y="92" key="SettingsEditor" timestamp="1602603890848">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state x="738" y="92" key="SettingsEditor/0.0.1920.1054@0.0.1920.1054" timestamp="1602603890848" />
<state x="100" y="99" width="1720" height="855" key="VCS.FileHistoryDialog" timestamp="1602604295150">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state x="100" y="99" width="1720" height="855" key="VCS.FileHistoryDialog/0.0.1920.1054@0.0.1920.1054" timestamp="1602604295150" />
<state x="100" y="99" width="1720" height="855" key="com.intellij.history.integration.ui.views.DirectoryHistoryDialog" timestamp="1602597391150">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state x="100" y="99" width="1720" height="855" key="com.intellij.history.integration.ui.views.DirectoryHistoryDialog/0.0.1920.1054@0.0.1920.1054" timestamp="1602597391150" />
<state x="623" y="270" width="673" height="512" key="find.popup" timestamp="1602599001638">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state x="623" y="270" width="673" height="512" key="find.popup/0.0.1920.1054@0.0.1920.1054" timestamp="1602599001638" />
<state x="440" y="285" width="1009" height="647" key="org.intellij.images.editor.actions.BackgroundImageDialog" timestamp="1602598923528">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state x="440" y="285" width="1009" height="647" key="org.intellij.images.editor.actions.BackgroundImageDialog/0.0.1920.1054@0.0.1920.1054" timestamp="1602598923528" />
<state x="623" y="231" width="672" height="678" key="search.everywhere.popup" timestamp="1602599024210">
<screen x="0" y="0" width="1920" height="1054" />
</state>
<state x="623" y="231" width="672" height="678" key="search.everywhere.popup/0.0.1920.1054@0.0.1920.1054" timestamp="1602599024210" />
</component> </component>
</project> </project>

View File

@ -1,8 +1,26 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace AusPostCode { namespace AusPostCode {
public class Barcode { public class Barcode {
public Dictionary<int, string> FormatTable = new Dictionary<int, string>() { public enum BarcodeFragment {
FormatControlCode,
SortingCode,
CustomerInformation,
ErrorCorrection,
}
public enum EncodingFormat {
N,
C,
BarToDecimal,
}
private int _formatCode;
public Dictionary<int, string> FormatTable = new Dictionary<int, string> {
[0] = "Null Customer Barcode", [0] = "Null Customer Barcode",
[11] = "Standard Customer Barcode", [11] = "Standard Customer Barcode",
[52] = "Customer Business Reply Paid", [52] = "Customer Business Reply Paid",
@ -10,14 +28,95 @@ namespace AusPostCode {
[62] = "Customer Barcode 3", [62] = "Customer Barcode 3",
[67] = "Customer Business Reply Paid", [67] = "Customer Business Reply Paid",
[72] = "International Business Reply Paid", [72] = "International Business Reply Paid",
[77] = "International Business Reply Paid" [77] = "International Business Reply Paid",
}; };
public int SortingCode { get; set; }
public int CustomerInformation { get; set; }
public string Code { get; set; }
public Barcode(string code) { public Barcode(string code) {
Code = code; Code = code;
// - check for start and end bars
if (Code.Substring(0, 2) != "13") {
Warnings.Add("Couldn't find Start Bars");
Code = $"13{Code}";
}
if (Code.Substring(Code.Length - 3, 2) != "13") {
Warnings.Add("Couldn't find End Bars");
Code = $"{Code}13";
}
// process Format Control Code
_formatCode = int.Parse(Decode(GetFragment(BarcodeFragment.FormatControlCode), EncodingFormat.N));
Console.WriteLine(Format);
// process Sorting Code Field
SortingCode = int.Parse(Decode(GetFragment(BarcodeFragment.SortingCode), EncodingFormat.N));
Console.WriteLine($"Sorting code: {SortingCode}");
}
public int SortingCode { get; set; }
public int CustomerInformation { get; set; }
public string Format => FormatTable.ContainsKey(_formatCode) ? FormatTable[_formatCode] : $"Unknown ({_formatCode})";
private List<string> Warnings { get; set; } = new List<string>();
private string Code { get; set; }
private string GetFragment(BarcodeFragment barcodeFragment) {
return barcodeFragment switch {
BarcodeFragment.FormatControlCode => Code.Substring(2, 4),
BarcodeFragment.SortingCode => Code.Substring(6, 16),
BarcodeFragment.CustomerInformation when _formatCode == 59 => Code.Substring(22, 16),
BarcodeFragment.CustomerInformation when _formatCode == 62 => Code.Substring(22, 31),
BarcodeFragment.CustomerInformation => null, // format doesn't support the customer information field
BarcodeFragment.ErrorCorrection => Code.Substring(Code.Length - 15,
12), // the error correction bars are always immediately before the stop bars
_ => throw new ArgumentOutOfRangeException(nameof(barcodeFragment), barcodeFragment, null),
};
}
private static string Decode(string input, EncodingFormat format) {
// bool badData;
var chunkLength = format == EncodingFormat.N ? 2 : 3;
if (input.Length % 2 != 0) {
throw new ArgumentException($"Input length must be a multiple of {chunkLength}.", nameof(input));
}
var rx = new Regex("^[0123]+$");
if (!rx.IsMatch(input)) {
throw new ArgumentException("Input length must be a quaternary number.", nameof(input));
}
var sb = new StringBuilder();
for (var i = 0; i < input.Length; i += chunkLength) {
var chunk = input.Substring(i, chunkLength);
switch (format) {
case EncodingFormat.N:
// format N supports the digits 0 through 9, and nothing else.
// digits 0 through 8 are stored as their ternary representations, while 9 is stored as "30".
if (chunk == "30") {
sb.Append(9);
}
else if (chunk.Contains("3")) {
// not a ternary number
throw new ArgumentException($"{chunk} is not a valid identifier for format {format.ToString()}.");
}
else {
sb.Append(BaseConversion.FromBase(chunk, 3));
}
break;
case EncodingFormat.C:
break;
case EncodingFormat.BarToDecimal:
break;
default:
throw new ArgumentOutOfRangeException(nameof(format), format, null);
}
}
return sb.ToString();
} }
} }
} }

70
BaseConversion.cs Normal file
View File

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace AusPostCode {
public static class BaseConversion {
// honestly surprised c# doesn't do this out of the box
private static readonly char[] Characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
// thanks to https://stackoverflow.com/a/35004409
private static readonly Dictionary<char, int> CharacterIndices =
Characters.Select((c, i) => new {Char = c, Index = i}).ToDictionary(c => c.Char, c => c.Index);
public static string ToBase(int num, int numberBase) {
if (numberBase > Characters.Length) {
throw new ArgumentOutOfRangeException(
nameof(numberBase),
$"Base must be below {Characters.Length}"
);
}
if (Math.Abs(num) == 0) {
return num.ToString();
}
var digits = new List<char>();
var negative = num < 0;
while (num > 0) {
digits.Add(Characters[num % numberBase]);
num /= numberBase;
}
digits.Reverse();
return (negative ? "-" : "") + string.Join("", digits);
}
public static int FromBase(string num, int numberBase) {
if (numberBase > Characters.Length) {
throw new ArgumentOutOfRangeException(
nameof(numberBase),
$"Base must be below {Characters.Length}"
);
}
var negative = false;
if (num.StartsWith("-")) {
// it's a negative number
negative = true;
num = num.Substring(1);
}
var x = num.ToCharArray();
var result = 0;
// thanks to https://stackoverflow.com/a/35004409 again for this 0uo
for (var i = 0; i < x.Length; i++) {
result += CharacterIndices[x[i]] * (int) Math.Pow(numberBase, x.Length - i - 1);
}
if (negative) {
result *= -1;
}
return result;
}
}
}

View File

@ -1,2 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Lynnesbian/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -1,37 +1,36 @@
/* /*
AusPostCode - A program for parsing and creating Australia Post barcodes. AusPostCode - A program for parsing and creating Australia Post barcodes.
Copyright (C) 2020 Lynnesbian Copyright (C) 2020 Lynnesbian
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System; using System;
using CommandLine; using CommandLine;
namespace AusPostCode { namespace AusPostCode {
internal class Program { internal class Program {
private static void Main(string[] args) {
public class Options { Console.WriteLine("Hello World!");
[Option('d', "decode", Required = false, const string testCode = "1301012112011202120020300110110322113";
HelpText = "Decode the text passed in, turning it into human readable information.")] var barcode = new Barcode(testCode);
public bool Decode { get; set; } }
}
public class Options {
private static void Main(string[] args) { [Option('d', "decode", Required = false,
Console.WriteLine("Hello World!"); HelpText = "Decode the text passed in, turning it into human readable information.")]
string testCode = "3111961842093257385431"; public bool Decode { get; set; }
var barcode = new Barcode(testCode); }
} }
} }
}