using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace POS.Provider
{
public class ISO8583
{
readonly int[] VLen = new int[130];
readonly int[] FLen = new int[130];
public ISO8583()
{
#region VLEN
VLen[2] = 2;
VLen[32] = 2;
VLen[33] = 2;
VLen[34] = 2;
VLen[35] = 2;
VLen[36] = 3;
VLen[44] = 2;
VLen[45] = 2;
VLen[46] = 3;
VLen[47] = 3;
VLen[48] = 3;
VLen[54] = 3;
VLen[55] = 3;
VLen[56] = 3;
VLen[57] = 3;
VLen[58] = 3;
VLen[59] = 3;
VLen[60] = 1;
VLen[61] = 3;
VLen[62] = 3;
VLen[63] = 3;
VLen[72] = 3;
VLen[99] = 2;
VLen[100] = 2;
VLen[102] = 2;
VLen[103] = 2;
VLen[104] = 3;
VLen[105] = 3;
VLen[106] = 3;
VLen[107] = 3;
VLen[108] = 3;
VLen[109] = 3;
VLen[110] = 3;
VLen[111] = 3;
VLen[112] = 3;
VLen[113] = 2;
VLen[114] = 3;
VLen[115] = 3;
VLen[116] = 3;
VLen[117] = 3;
VLen[118] = 3;
VLen[119] = 3;
VLen[120] = 3;
VLen[121] = 3;
VLen[122] = 3;
VLen[123] = 3;
VLen[124] = 3;
VLen[125] = 2;
VLen[126] = 1;
VLen[127] = 3;
#endregion
#region FLEN
FLen[0] = 16;
FLen[1] = 16;
FLen[3] = 6;
FLen[4] = 12;
FLen[5] = 12;
FLen[6] = 12;
FLen[7] = 10;
FLen[8] = 8;
FLen[9] = 8;
FLen[10] = 8;
FLen[11] = 6;
FLen[12] = 6;
FLen[13] = 4;
FLen[14] = 4;
FLen[15] = 4;
FLen[16] = 4;
FLen[17] = 4;
FLen[18] = 4;
FLen[19] = 3;
FLen[20] = 3;
FLen[21] = 3;
FLen[22] = 3;
FLen[23] = 3;
FLen[24] = 3;
FLen[25] = 2;
FLen[26] = 2;
FLen[27] = 1;
FLen[28] = 8;
FLen[29] = 8;
FLen[30] = 8;
FLen[31] = 8;
FLen[37] = -12;
FLen[38] = -6;
FLen[39] = -2;
FLen[40] = -3;
FLen[41] = -8;
FLen[42] = -15;
FLen[43] = -40;
FLen[49] = -3;
FLen[50] = -3;
FLen[51] = -3;
FLen[52] = -16;
FLen[53] = 18;
FLen[64] = -4;
FLen[65] = -16;
FLen[66] = 1;
FLen[67] = 2;
FLen[68] = 3;
FLen[69] = 3;
FLen[70] = 3;
FLen[71] = 4;
FLen[73] = 6;
FLen[74] = 10;
FLen[75] = 10;
FLen[76] = 10;
FLen[77] = 10;
FLen[78] = 10;
FLen[79] = 10;
FLen[80] = 10;
FLen[81] = 10;
FLen[82] = 12;
FLen[83] = 12;
FLen[84] = 12;
FLen[85] = 12;
FLen[86] = 15;
FLen[87] = 15;
FLen[88] = 15;
FLen[89] = 15;
FLen[90] = 42;
FLen[91] = -1;
FLen[92] = 2;
FLen[93] = 5;
FLen[94] = -7;
FLen[95] = -42;
FLen[96] = -8;
FLen[97] = 16;
FLen[98] = -25;
FLen[101] = -17;
FLen[128] = -16;
#endregion
}
public string ToPackage(string[] v, string _ISO)
{
try
{
v = v.ToDomain();
for (int i = 0; i <= 128; i++)
{
if (v[i] == null || v[i] == "")
continue;
_ISO += VLen[i] < 1 ?
FLen[i] < 0 ?
v[i].PadRight(Math.Abs(FLen[i]), ' ').Substring(0, Math.Abs(FLen[i])) :
v[i].PadLeft(FLen[i], '0').Substring(v[i].PadLeft(FLen[i], '0').Length - Math.Abs(FLen[i]), Math.Abs(FLen[i])) :
(v[i].Length.ToString().PadLeft(VLen[i], '0') + v[i]);
}
return _ISO;
}
catch (Exception ex)
{
throw new Exception("打包失败:" + ex);
}
}
public string[] UnPackage(string s)
{
try
{
var v = new string[130];
var _OneBlock = "";
var _TwoBlock = "";
var x = 4;
for (var i = 0; i <= 128; i++)
{
if (i == 0)
{
v[129] = s.Skip(i).Take(x).ToStr();
v[i] = s.Skip(x).Take(FLen[i]).ToStr();
_OneBlock = v[i].ToBinary();
x += FLen[i];
continue;
}
if (i == 1)
{
if (_OneBlock.Substring(i - 1, 1) == "1")
{
v[i] = s.Skip(x).Take(FLen[i]).ToStr();
_TwoBlock = v[i].ToBinary();
x += FLen[i];
}
continue;
}
if (i >= 65)
if (_TwoBlock == "" || _TwoBlock == "0000000000000000000000000000000000000000000000000000000000000000")
break;
else
{
if (VLen[i] > 0)
{
if (_TwoBlock.Substring(i - 64 - 1, 1) == "1")
{
var w = Convert.ToInt16(s.Skip(x).Take(VLen[i]).ToStr());
v[i] = s.Skip(x + VLen[i]).Take(w).ToStr();
x += (w + VLen[i]);
}
}
else
{
if (_TwoBlock.Substring(i - 64 - 1, 1) == "1")
{
v[i] = s.Skip(x).Take(FLen[i].ToAbs()).ToStr();
x += FLen[i].ToAbs();
}
}
}
else
{
if (VLen[i] > 0)
{
if (_OneBlock.Substring(i - 1, 1) == "1")
{
var w = Convert.ToInt16(s.Skip(x).Take(VLen[i]).ToStr());
v[i] = s.Skip(x + VLen[i]).Take(w).ToStr();
x += (w + VLen[i]);
}
}
else
{
if (_OneBlock.Substring(i - 1, 1) == "1")
{
v[i] = s.Skip(x).Take(FLen[i].ToAbs()).ToStr();
x += FLen[i].ToAbs();
}
}
}
}
return v;
}
catch (Exception ex)
{
throw new Exception("解包失败:" + ex);
}
}
}
public class ISO8583Model
{
}
public static class ISO8583ToolBox
{
public static string[] ToDomain(this string[] v)
{
var _OneBlock = "";
for (var i = 2; i <= 64; i++)
_OneBlock += (v[i] != null && v[i] != "") ? "1" : "0";
var _TwoBlock = "";
for (var i = 65; i <= 128; i++)
_TwoBlock += (v[i] != null && v[i] != "") ? "1" : "0";
_OneBlock = _TwoBlock == "0000000000000000000000000000000000000000000000000000000000000000" ? "0" + _OneBlock : "1" + _OneBlock;
v[0] = _OneBlock.ToHex().PadLeft(16, '0');
v[1] = _TwoBlock.ToHex().PadLeft(16, '0') == "0000000000000000" ? null : _TwoBlock.ToHex().PadLeft(16, '0');
return v;
}
public static string ToBinary(this string x)
{
var s = "";
for (int i = 0; i <= 15; i++)
s += x.Substring(i, 1).ToBin();
return s;
}
public static string ToBin(this string s)
{
return s == "0" ? "0000" :
s == "1" ? "0001" :
s == "2" ? "0010" :
s == "3" ? "0011" :
s == "4" ? "0100" :
s == "5" ? "0101" :
s == "6" ? "0110" :
s == "7" ? "0111" :
s == "8" ? "1000" :
s == "9" ? "1001" :
s == "A" ? "1010" :
s == "B" ? "1011" :
s == "C" ? "1100" :
s == "D" ? "1101" :
s == "E" ? "1110" :
s == "F" ? "1111" : "";
}
public static string ToHex(this string s)
{
return String.Format("{0:X1}", Convert.ToInt64(s, 2));
}
public static string ToStr(this IEnumerable<Char> s)
{
return String.Join("", s);
}
public static int ToAbs(this int i)
{
return Math.Abs(i);
}
}
}