Advertisement
Guest User

OneCode C# encode/decode

a guest
Jul 31st, 2013
703
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.37 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace OneCode
  7. {
  8.     class Program
  9.     {
  10.         static void Main(string[] args)
  11.         {
  12.             string encode = OneCode.OneCodeBars("00310999999999001724302155627");
  13.             string encode1 = OneCode.OneCodeBars("01234567094987654321");
  14.             string encode2 = OneCode.OneCodeBars("0123456709498765432101234");
  15.             string encode3 = OneCode.OneCodeBars("01234567094987654321012345678");
  16.             string encode4 = OneCode.OneCodeBars("0123456709498765432101234567891");
  17.             string encode5 = OneCode.OneCodeBars("7277777777777777777777777777777");
  18.  
  19.             string decode = OneCode.OneCodeDecode(encode);
  20.             string decode1 = OneCode.OneCodeDecode(encode1);
  21.             string decode2 = OneCode.OneCodeDecode(encode2);
  22.             string decode3 = OneCode.OneCodeDecode(encode3);
  23.             string decode4 = OneCode.OneCodeDecode(encode4);
  24.             string decode5 = OneCode.OneCodeDecode(encode5);
  25.         }
  26.     }
  27.  
  28.     public static class OneCode
  29.     {
  30.         // for more information and specs check
  31.         // http://ribbs.usps.gov/onecodesolution/USPS-B-3200D001.pdf
  32.         private static Int32 table2of13Size = 78;
  33.         private static Int32 table5of13Size = 1287;
  34.         private static Int64 entries2of13 = table5of13Size;
  35.         private static Int64 entries5of13 = table2of13Size;
  36.         private static Int32[] table2of13 = OneCodeInfo(1);
  37.         private static Int32[] table5of13 = OneCodeInfo(2);
  38.         private static Int32[] table2of13ArrayPtr = table2of13;
  39.         private static Int32[] table5of13ArrayPtr = table5of13;
  40.         private static Decimal[][] codewordArray = OneCodeInfo();
  41.         private static Int32[] BarTopCharacterIndexArray = new Int32[] { 4, 0, 2, 6, 3, 5, 1, 9, 8, 7, 1, 2, 0, 6, 4, 8, 2, 9, 5, 3, 0, 1, 3, 7, 4, 6, 8, 9, 2, 0, 5, 1, 9, 4, 3, 8, 6, 7, 1, 2, 4, 3, 9, 5, 7, 8, 3, 0, 2, 1, 4, 0, 9, 1, 7, 0, 2, 4, 6, 3, 7, 1, 9, 5, 8 };
  42.         private static Int32[] BarBottomCharacterIndexArray = new Int32[] { 7, 1, 9, 5, 8, 0, 2, 4, 6, 3, 5, 8, 9, 7, 3, 0, 6, 1, 7, 4, 6, 8, 9, 2, 5, 1, 7, 5, 4, 3, 8, 7, 6, 0, 2, 5, 4, 9, 3, 0, 1, 6, 8, 2, 0, 4, 5, 9, 6, 7, 5, 2, 6, 3, 8, 5, 1, 9, 8, 7, 4, 0, 2, 6, 3 };
  43.         private static Int32[] BarTopCharacterShiftArray = new Int32[] { 3, 0, 8, 11, 1, 12, 8, 11, 10, 6, 4, 12, 2, 7, 9, 6, 7, 9, 2, 8, 4, 0, 12, 7, 10, 9, 0, 7, 10, 5, 7, 9, 6, 8, 2, 12, 1, 4, 2, 0, 1, 5, 4, 6, 12, 1, 0, 9, 4, 7, 5, 10, 2, 6, 9, 11, 2, 12, 6, 7, 5, 11, 0, 3, 2 };
  44.         private static Int32[] BarBottomCharacterShiftArray = new Int32[] { 2, 10, 12, 5, 9, 1, 5, 4, 3, 9, 11, 5, 10, 1, 6, 3, 4, 1, 10, 0, 2, 11, 8, 6, 1, 12, 3, 8, 6, 4, 4, 11, 0, 6, 1, 9, 11, 5, 3, 7, 3, 10, 7, 11, 8, 2, 10, 3, 5, 8, 0, 3, 12, 11, 8, 4, 5, 1, 3, 0, 7, 12, 9, 8, 10 };
  45.  
  46.         public static String OneCodeBars(this String source)
  47.         {
  48.             if(String.IsNullOrEmpty(source))
  49.                 return null;
  50.             source = TrimOff(source, " -.");
  51.             if(!System.Text.RegularExpressions.Regex.IsMatch(source, "^[0-9][0-4](([0-9]{18})|([0-9]{23})|([0-9]{27})|([0-9]{29}))$"))
  52.                 return String.Empty;
  53.             String encoded = String.Empty;
  54.             Int64 l = 0L;
  55.             String zip = source.Substring(20);
  56.             switch(zip.Length)
  57.             {
  58.                 case 5:
  59.                     l = Int64.Parse(zip) + 1;
  60.                     break;
  61.                 case 9:
  62.                     l = Int64.Parse(zip) + 100001;
  63.                     break;
  64.                 case 11:
  65.                     l = Int64.Parse(zip) + 1000100001;
  66.                     break;
  67.             }
  68.             Decimal v = l;
  69.             v = v * 10 + Int32.Parse(source.Substring(0, 1));
  70.             v = v * 5 + Int32.Parse(source.Substring(1, 1));
  71.             String ds = v.ToString() + source.Substring(2, 18);
  72.             Int32[] byteArray = new Int32[13];
  73.             byteArray[12] = (Int32)(l & 255);
  74.             byteArray[11] = (Int32)(l >> 8 & 255);
  75.             byteArray[10] = (Int32)(l >> 16 & 255);
  76.             byteArray[9] = (Int32)(l >> 24 & 255);
  77.             byteArray[8] = (Int32)(l >> 32 & 255);
  78.             OneCodeMathMultiply(ref byteArray, 13, 10);
  79.             OneCodeMathAdd(ref byteArray, 13, Int32.Parse(source.Substring(0, 1)));
  80.             OneCodeMathMultiply(ref byteArray, 13, 5);
  81.             OneCodeMathAdd(ref byteArray, 13, Int32.Parse(source.Substring(1, 1)));
  82.             for(var i = 2; i <= 19; i++)
  83.             {
  84.                 OneCodeMathMultiply(ref byteArray, 13, 10);
  85.                 OneCodeMathAdd(ref byteArray, 13, Int32.Parse(source.Substring(i, 1)));
  86.             }
  87.             Int32 fcs = OneCodeMathFcs(byteArray);
  88.             for(var i = 0; i <= 9; i++)
  89.             {
  90.                 codewordArray[i][0] = entries2of13 + entries5of13;
  91.                 codewordArray[i][1] = 0;
  92.             }
  93.             codewordArray[0][0] = 659;
  94.             codewordArray[9][0] = 636;
  95.             OneCodeMathDivide(ds);
  96.             codewordArray[9][1] *= 2;
  97.             if(fcs >> 10 != 0)
  98.                 codewordArray[0][1] += 659;
  99.             Int32[] ai = new Int32[65], ai1 = new Int32[65];
  100.             Decimal[][] ad = new Decimal[11][];
  101.             for(var i = 0; i <= 9; i++)
  102.                 ad[i] = new Decimal[2];
  103.             for(var i = 0; i <= 9; i++)
  104.             {
  105.                 if(codewordArray[i][1] >= (Decimal)(entries2of13 + entries5of13))
  106.                     return String.Empty;
  107.                 ad[i][0] = 8192;
  108.                 if(codewordArray[i][1] >= (Decimal)entries2of13)
  109.                     ad[i][1] = table2of13[(Int32)(codewordArray[i][1] - entries2of13)];
  110.                 else
  111.                     ad[i][1] = table5of13[(Int32)codewordArray[i][1]];
  112.             }
  113.             for(var i = 0; i <= 9; i++) if((fcs & 1 << i) != 0)
  114.                     ad[i][1] = ~(Int32)ad[i][1] & 8191;
  115.             for(var i = 0; i <= 64; i++)
  116.             {
  117.                 ai[i] = (Int32)ad[BarTopCharacterIndexArray[i]][1] >> BarTopCharacterShiftArray[i] & 1;
  118.                 ai1[i] = (Int32)ad[BarBottomCharacterIndexArray[i]][1] >> BarBottomCharacterShiftArray[i] & 1;
  119.             }
  120.             encoded = "";
  121.             // T: track, D: descender, A: ascender, F: full bar
  122.             for(var i = 0; i <= 64; i++)
  123.             {
  124.                 if(ai[i] == 0)
  125.                     encoded += (ai1[i] == 0) ? "T" : "D";
  126.                 else
  127.                     encoded += (ai1[i] == 0) ? "A" : "F";
  128.             }
  129.             return encoded;
  130.         }
  131.  
  132.         public static String OneCodeDecode(this String source)
  133.         {
  134.             if(!System.Text.RegularExpressions.Regex.IsMatch(source, "^[ADFT]{65}$"))
  135.                 return String.Empty;
  136.             Int32[] ad = new Int32[10], byteArray = new Int32[13];
  137.             Int32 r = 0;
  138.             System.Text.StringBuilder bin = new System.Text.StringBuilder();
  139.             String result = String.Empty;
  140.             for(var i = 0; i <= 64; i++)
  141.             {
  142.                 if(source[i] == 'T')
  143.                     bin.Append("00");
  144.                 else if(source[i] == 'D')
  145.                     bin.Append("01");
  146.                 else if(source[i] == 'A')
  147.                     bin.Append("10");
  148.                 else
  149.                     bin.Append("11");
  150.             }
  151.             String bits = bin.ToString();
  152.             for(var i = 0; i <= 128; i += 2)
  153.             {
  154.                 Int32 v = Convert.ToInt32(bits.Substring(i, 2), 2), k = i / 2;
  155.                 if((v > 1))
  156.                     ad[BarTopCharacterIndexArray[k]] += 1 << BarTopCharacterShiftArray[k];
  157.                 if((v % 2 == 1))
  158.                     ad[BarBottomCharacterIndexArray[k]] += 1 << BarBottomCharacterShiftArray[k];
  159.             }
  160.             for(var i = 0; i <= 9; i++)
  161.             {
  162.                 Int32 test = ad[i], index = Array.IndexOf(table5of13, test);
  163.                 if((index < 0))
  164.                 {
  165.                     test = ~test & 8191;
  166.                     index = Array.IndexOf(table5of13, test);
  167.                     if((index < 0))
  168.                     {
  169.                         test = ad[i]; //bgh
  170.                         index = Array.IndexOf(table2of13, test);
  171.                         if (index < 0) //bgh
  172.                         {
  173.                             test = ~test & 8191; //bgh
  174.                             index = Array.IndexOf(table2of13, test); //bgh
  175.                         }                  
  176.                         index += 1287;
  177.                     }
  178.                 }
  179.                 ad[i] = index;
  180.             }
  181.             ad[9] = (Int32)ad[9] / 2;
  182.             if((ad[0] > 658))
  183.                 ad[0] -= 659;
  184.             OneCodeMathMultiply(ref byteArray, 13, 659); //added missing multiply
  185.             OneCodeMathAdd(ref byteArray, 13, ad[0]);
  186.             for(var i = 1; i <= 8; i++)
  187.             {
  188.                 OneCodeMathMultiply(ref byteArray, 13, 1365);
  189.                 OneCodeMathAdd(ref byteArray, 13, ad[i]);
  190.             }
  191.             OneCodeMathMultiply(ref byteArray, 13, 636);
  192.             OneCodeMathAdd(ref byteArray, 13, ad[9]);
  193.             r = OneCodeMathMod(byteArray, 10);
  194.             result = r.ToString() + result;
  195.             for(var i = 2; i <= 18; i++) //bgh only loop 2 to 18 because the 19th test should be mod 5
  196.             {
  197.                 OneCodeMathAdd(ref byteArray, 13, -r);
  198.                 OneCodeMathDivide(ref byteArray, 10);
  199.                 r = OneCodeMathMod(byteArray, 10);
  200.                 result = r.ToString() + result;
  201.             }
  202.  
  203.             OneCodeMathAdd(ref byteArray, 13, -r); //bgh
  204.             OneCodeMathDivide(ref byteArray, 10); //bgh
  205.             r = OneCodeMathMod(byteArray, 5); //bgh   19 divide by 10 is then mod 5
  206.             result = r.ToString() + result; //bgh
  207.             OneCodeMathAdd(ref byteArray, 13, -r); //bgh
  208.             OneCodeMathDivide(ref byteArray, 5); //bgh now divide by 5 and mod 10
  209.             r = OneCodeMathMod(byteArray, 10); //bgh
  210.             result = r.ToString() + result; //bgh last result
  211.             OneCodeMathAdd(ref byteArray, 13, -r); //bgh
  212.             OneCodeMathDivide(ref byteArray, 10); //one last divide by 10
  213.  
  214.             Byte[] restBytes = new Byte[8];
  215.             for(var i = 12; i >= 5; i += -1)
  216.                 restBytes[12 - i] = (Byte)byteArray[i];
  217.             Int64 rest = BitConverter.ToInt64(restBytes, 0);
  218.             if(rest > 1000100001)
  219.                 result += (rest - 1000100001).ToString().PadLeft(11, '0');
  220.             else if(rest > 100001)
  221.                 result += (rest - 100001).ToString().PadLeft(9, '0');
  222.             else if(rest > 0)
  223.                 result += (rest - 1).ToString().PadLeft(5, '0');
  224.             return result;
  225.         }
  226.  
  227.         private static Int32[] OneCodeInfo(Int32 topic)
  228.         {
  229.             switch(topic)
  230.             {
  231.                 case 1:
  232.                     Int32[] a = new Int32[table2of13Size + 2];
  233.                     OneCodeInitializeNof13Table(ref a, 2, table2of13Size);
  234.                     entries5of13 = table2of13Size;
  235.                     return a;
  236.                 case 2:
  237.                     Int32[] b = new Int32[table5of13Size + 2];
  238.                     OneCodeInitializeNof13Table(ref b, 5, table5of13Size);
  239.                     entries2of13 = table5of13Size;
  240.                     return b;
  241.             }
  242.             return new int[2];
  243.         }
  244.  
  245.         private static Decimal[][] OneCodeInfo()
  246.         {
  247.             Decimal[][] da = new Decimal[11][];
  248.             try
  249.             {
  250.                 for(var i = 0; i <= 9; i++)
  251.                     da[i] = new Decimal[2];
  252.                 return da;
  253.             }
  254.             finally
  255.             {
  256.                 da = null;
  257.             }
  258.         }
  259.  
  260.         private static Boolean OneCodeInitializeNof13Table(ref Int32[] ai, Int32 i, Int32 j)
  261.         {
  262.             Int32 i1 = 0, j1 = j - 1;
  263.             for(var k = 0; k <= 8191; k++)
  264.             {
  265.                 Int32 k1 = 0;
  266.                 for(var l1 = 0; l1 <= 12; l1++) if((k & 1 << l1) != 0)
  267.                         k1 += 1;
  268.                 if(k1 == i)
  269.                 {
  270.                     Int32 l = OneCodeMathReverse(k) >> 3;
  271.                     Boolean flag = (k == l);
  272.                     if(l >= k)
  273.                     {
  274.                         if(flag)
  275.                         {
  276.                             ai[j1] = k;
  277.                             j1 -= 1;
  278.                         }
  279.                         else
  280.                         {
  281.                             ai[i1] = k;
  282.                             i1 += 1;
  283.                             ai[i1] = l;
  284.                             i1 += 1;
  285.                         }
  286.                     }
  287.                 }
  288.             }
  289.             return i1 == j1 + 1;
  290.         }
  291.  
  292.         private static Boolean OneCodeMathAdd(ref Int32[] bytearray, Int32 i, Int32 j)
  293.         {
  294.             if(j == 0)
  295.                 return true;
  296.             if(bytearray == null)
  297.                 return false;
  298.             if(i < 1)
  299.                 return false;
  300.             i -= 1;
  301.             bytearray[i] += j;
  302.             Int32 carry = 0;
  303.             if(j > 0)
  304.             {
  305.                 while(i > 0 & bytearray[i] > 255)
  306.                 {
  307.                     carry = (bytearray[i] >> 8);
  308.                     bytearray[i] = bytearray[i] % 256;
  309.                     i -= 1;
  310.                     bytearray[i] += carry;
  311.                 }
  312.             }
  313.             else
  314.             {
  315.                 while(i > 0 & bytearray[i] < 0)
  316.                 {
  317.                     carry = 1;
  318.                     bytearray[i] += 256;
  319.                     i -= 1;
  320.                     bytearray[i] -= carry;
  321.                 }
  322.             }
  323.             return true;
  324.         }
  325.  
  326.         private static Int32 OneCodeMathMod(Int32[] byteArray, Int32 d)
  327.         {
  328.             Int32 i = 0, r = 0, l = byteArray.Length;
  329.             while((i < 13))
  330.             {
  331.                 r <<= 8;
  332.                 r = r | byteArray[i];
  333.                 r = r % d;
  334.                 i += 1;
  335.             }
  336.             return r;
  337.         }
  338.  
  339.         private static void OneCodeMathDivide(ref Int32[] byteArray, Int32 d)
  340.         {
  341.             Int32 i = 0, r = 0, l = byteArray.Length;
  342.             while((i < l))
  343.             {
  344.                 r <<= 8;
  345.                 r = r | byteArray[i];
  346.                 byteArray[i] = (int)r / d;
  347.                 r = r % d;
  348.                 i += 1;
  349.             }
  350.         }
  351.  
  352.         private static void OneCodeMathDivide(String v)
  353.         {
  354.             // back to school - you may change it to use shitfing
  355.             Int32 j = 10;
  356.             String n = v;
  357.             for(var k = j - 1; k >= 1; k += -1)
  358.             {
  359.                 String r = String.Empty, copy = n, left = "0";
  360.                 Int32 divider = (Int32)codewordArray[k][0], l = copy.Length;
  361.                 for(var i = 1; i <= l; i++)
  362.                 {
  363.                     Int32 divident = Int32.Parse(copy.Substring(0, i));
  364.                     while(divident < divider & i < l - 1)
  365.                     {
  366.                         r = r + "0";
  367.                         i += 1;
  368.                         divident = Int32.Parse(copy.Substring(0, i));
  369.                     }
  370.                     r = r + (divident / divider).ToString();
  371.                     left = (divident % divider).ToString().PadLeft(i, '0');
  372.                     copy = left + copy.Substring(i);
  373.                 }
  374.                 n = r.TrimStart('0');
  375.                 if(String.IsNullOrEmpty(n))
  376.                     n = "0";
  377.                 codewordArray[k][1] = Int32.Parse(left);
  378.                 if(k == 1)
  379.                     codewordArray[0][1] = Int32.Parse(r);
  380.             }
  381.         }
  382.  
  383.         private static Int32 OneCodeMathFcs(Int32[] bytearray)
  384.         {
  385.             Int32 c = 3893, i = 2047, j = bytearray[0] << 5;
  386.             for(var b = 2; b <= 7; b++)
  387.             {
  388.                 if(((i ^ j) & 1024) != 0)
  389.                     i = (i << 1) ^ c;
  390.                 else
  391.                     i = i << 1;
  392.                 i = i & 2047;
  393.                 j = j << 1;
  394.             }
  395.             for(var l = 1; l <= 12; l++)
  396.             {
  397.                 Int32 k = bytearray[l] << 3;
  398.                 for(var b = 0; b <= 7; b++)
  399.                 {
  400.                     if(((i ^ k) & 1024) != 0)
  401.                         i = (i << 1) ^ c;
  402.                     else
  403.                         i = i << 1;
  404.                     i = i & 2047;
  405.                     k = k << 1;
  406.                 }
  407.             }
  408.             return i;
  409.         }
  410.  
  411.         private static Boolean OneCodeMathMultiply(ref Int32[] bytearray, Int32 i, Int32 j)
  412.         {
  413.             if(bytearray == null)
  414.                 return false;
  415.             if(i < 1)
  416.                 return false;
  417.             Int32 l = 0, k = 0;
  418.             for(k = i - 1; k >= 1; k += -2)
  419.             {
  420.                 Int32 x = (bytearray[k] | (bytearray[k - 1] << 8)) * j + l;
  421.                 bytearray[k] = x & 255;
  422.                 bytearray[k - 1] = x >> 8 & 255;
  423.                 l = x >> 16;
  424.             }
  425.             if(k == 0)
  426.                 bytearray[0] = (bytearray[0] * j + l) & 255;
  427.             return true;
  428.         }
  429.  
  430.         private static Int32 OneCodeMathReverse(Int32 i)
  431.         {
  432.             Int32 j = 0;
  433.             for(var k = 0; k <= 15; k++)
  434.             {
  435.                 j <<= 1;
  436.                 j = j | i & 1;
  437.                 i >>= 1;
  438.             }
  439.             return j;
  440.         }
  441.  
  442.         private static String TrimOff(String source, String bad)
  443.         {
  444.             Int32 l = bad.Length - 1;
  445.             for(var i = 0; i <= l; i++)
  446.                 source = source.Replace(bad.Substring(i, 1), String.Empty);
  447.             return source;
  448.         }
  449.  
  450.     }
  451. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement