📄 ber.cs
字号:
k = 24;
}
}
}
public Universal(string s)
{
type = new BERtag(UniversalType.OctetString);
e = true;
b = (new ASCIIEncoding()).GetBytes(s);
len = (uint) b.Length;
}
public Universal(uint[] oid)
{
type = new BERtag(UniversalType.ObjectIdentifier);
e = true;
uint ln = 0;
int j;
for (j=1;j<oid.Length;j++)
ln += (uint)LengthOIDEl(oid[j]);
b = new byte[ln];
len = 0;
if (oid[0]!=1 || oid[1]!=3)
throw(new Exception("OID must begin with .1.3"));
PutOIDEl(43);
for (j=2;j<oid.Length;j++)
PutOIDEl(oid[j]);
}
public Universal(ArrayList a)
{
type = new BERtag(0,true,0);
e = true;
ArrayList al = new ArrayList(a.Count);
val = al;
for (int j=0;j<a.Count;j++)
{
object o = a[j];
if (o is bool)
al.Add(new Universal((bool)o));
else if (o is int)
al.Add(new Universal((int)o));
else if (o is BitSet)
al.Add(new Universal((BitSet)o));
else if (o is string)
al.Add(new Universal((string)o));
else if (o is uint[])
al.Add(new Universal((uint[])o));
}
}
public Universal(BERtag t,params Universal[] obs)
{
type = t;
e = true;
val = obs;
}
public Universal(params Universal[] obs) : this(new BERtag(0,true,16),obs) {}
protected bool Children(Stream s) // handle SEQUENCE, set len field
{
if (type.isEndMarker)
return true;
byte x = ReadByte(s);
if (x==0x80) // use end-of-contents marker
{
ArrayList al = new ArrayList();
val = al;
Universal bb;
do
{
bb = Creator(s);
al.Add(bb);
} while (!bb.type.isEndMarker);
return true;
}
len = (uint)ReadLength(s,x);
b = new byte[len];
if (type.comp)
{
ArrayList c = new ArrayList();
ulong n = 0;
Universal d;
do
{
d = Creator(s);
n += d.Length+LengthLength(d.Length)+1+d.type.ExtLength();
c.Add(d);
} while (n<len);
Universal[] obs = Creators(c.Count);
for (int i=0;i<c.Count;i++)
obs[i] = (Universal)c[i];
val = obs;
return true;
}
return false;
}
public Universal(Stream s)
{
e = false;
type = CreateTag(s);
if (Children(s))
{
if(type.tag!=0x10)
CombineValues();
return;
}
if (len>0)
s.Read(b,0,(int)len);
ValueOf(len);
}
protected ulong ReadLength(Stream s,byte x) // x is initial octet
{
if ((x&0x80)==0)
return (ulong)x;
ulong u = 0;
int n = (int)(x&0x7f);
for (int j=0;j<n;j++)
{
x = ReadByte(s);
u = (u<<8) + (ulong)x;
}
return u;
}
protected void WriteLength(Stream s,ulong a) // excluding initial octet
{
if (a==0)
{
s.WriteByte(0);
return;
}
byte[] c = new byte[16];
int j = 0;
while (a>0)
{
c[j++] = (byte)(a&0xff);
a = a>>8;
}
s.WriteByte((byte)(0x80|j));
while (j>0)
{
int x = c[--j];
s.WriteByte((byte)x);
}
}
protected uint LengthLength(ulong a) // excluding initial octet
{
uint j=0;
while (a>0)
{
j++;
a = a>>8;
}
return j;
}
void CombineValues() // handle some special cases
{
Universal[] a = (Universal[])val;
int j;
switch ((UniversalType)(type.ToByte()))
{
case UniversalType.BitString: // 8.6.3
BitSet r = (BitSet)a[0].val;
for (j=1;j<a.Length;j++)
r = r.Cat((BitSet)a[j].val);
val = r; break;
case UniversalType.OctetString: // 8.7.3
string s = (string)a[0].val;
for (j=1;j<a.Length;j++)
s += (string)a[j].val;
val = s; break;
}
}
protected virtual bool ValueOf(uint n)
{
int j=0;
switch ((UniversalType)(type.ToByte()))
{
case UniversalType.Boolean: val = (b[0]>0); break;
case UniversalType.Integer:
val = (int)new Integer(b); break;
case UniversalType.BitString:
byte r = b[0];
BitSet bs = new BitSet(n*8-r); // 8.6.2
for (j=0;j<bs.size;j++)
bs.bits[j] = (b[4*j]<<24)|(b[4*j+1]<<16)|(b[4*j+2]<<8)|b[4*j+3];
val = bs; break;
case UniversalType.OctetString:
if (n==8||n==11) // may be a date
{
uint yr = b[0];
yr = yr*256 + b[1];
uint mo = b[2];
uint dy = b[3];
if (yr<2005&&yr>1990 && mo<13 && dy<32)
{
val = ""+dy+"/"+mo+"/"+yr; break;
}
}
val = (new ASCIIEncoding()).GetString(b,0,(int)n); break;
case UniversalType.Null:
val = null;
break;
case UniversalType.ObjectIdentifier:
ArrayList al = new ArrayList();
int p = 0;
while (p<n)
al.Add(GetOIDEl(ref p));
uint[] oid;
if (((uint)al[0])==43)
{
oid = new uint[al.Count+1];
oid[0] = 1;
oid[1] = 3;
for (j=1;j<al.Count;j++)
oid[j+1] = (uint)al[j];
}
else // can happen that oid is .0??
{
// throw(new Exception("OID must begin with .1.3"));
oid = new uint[al.Count];
for (j=0;j<al.Count;j++)
oid[j] = (uint)al[j];
}
val = oid; break;
case UniversalType.Real:
val = (double)new Real(b); break;
default:
val = type.ToString()+" unimplemented"; break;
}
return true;
}
public ulong Length
{
get
{
if (e && val is Universal[])
{
ulong r = 0;
Universal[] a = (Universal[])val;
for (int j=0;j<a.Length;j++)
{
Universal u = a[j];
r += u.Length+LengthLength(u.Length)+1+u.type.ExtLength();
}
return r;
}
else
return len;
}
}
public void Send(Stream s) // create the external representation
{
type.Send(s);
WriteLength(s,Length);
if (e && val is Universal[])
{
Universal[] a = (Universal[])val;
for (int j=0;j<a.Length;j++)
a[j].Send(s);
}
else
s.Write(b,0,(int)Length);
}
protected void PutOIDEl(uint a)
{
if (a==0)
{
b[len++] = 0;
return;
}
byte[] c = new byte[16];
int j = 0;
while (a>0)
{
c[j++] = (byte)(a&0x7f);
a = a>>7;
}
while (j>0)
{
int x = c[--j];
if (j>0)
x |= 0x80;
b[len++] = (byte)x;
}
}
protected uint GetOIDEl(ref int p)
{
uint r = 0;
byte x;
do
{
x = b[p++];
r = (r<<7) + (uint)x&0x7f;
} while ((x&0x80)!=0);
return r;
}
uint LengthOIDEl(uint a)
{
uint j = 0;
if (a==0)
return 1;
while (a>0)
{
j++;
a = a>>7;
}
return j;
}
public object Value { get { return val; }}
public string Type()
{
string r = type.ToString();
if (type.comp)
{
r += "{\n";
Universal[] al = (Universal[])val;
for (int j=0;j<al.Length;j++)
{
r += al[j].Type();
if (j<al.Length-1)
r += ",\n";
}
r += "}";
}
return r;
}
public override string ToString()
{
string r = "";
if (type.comp)
{
r += "{\n";
Universal[] al = (Universal[])val;
for (int j=0;j<al.Length;j++)
{
r += al[j].ToString();
if (j<al.Length-1)
r += ",\n";
}
r += "}";
}
else
{
if (val==null)
ValueOf(len);
switch ((UniversalType)type.tag)
{
case UniversalType.BitString:
r += "["+val.ToString()+"]";
break;
case UniversalType.ObjectIdentifier:
uint[] oid = (uint[])val;
for (int k=0;k<oid.Length;k++)
r += "."+oid[k];
break;
case UniversalType.OctetString:
r += "\""+val.ToString()+"\"";
break;
case UniversalType.Null:
r += "NULL"; break;
default:
r += val.ToString();
break;
}
}
return r;
}
public void Dump()
{
string[] r = ToString().Split('\n');
for (int i=0;i<r.Length;i++)
System.Console.WriteLine(r[i]);
}
public Universal this[int ix]
{
get
{
Universal[] ls = (Universal[])Value;
return ls[ix];
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -