⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smsbase.cs

📁 短信PDU解码,国内其他PDU编码可以
💻 CS
字号:
using System;
using System.Text;
using System.Collections.Generic;

namespace SMSPDULib
{

	public enum SMSDirection
	{
		Received = 0,
		Submited = 1
	}

	public enum SMSType
	{
		SMS = 0,
		StatusReport = 1
	}

	public enum ValidityPeriodFormat
	{
		FieldNotPresent = 0,
		Relative = 0x10,
		Enhanced = 0x08,
		Absolute = 0x18
	}

	public abstract class SMSBase
	{
		#region Public Statics (Pops, Peeks, Gets)

		public static byte[] GetInvertBytes(string source)
		{
			byte[] bytes = GetBytes(source);

			Array.Reverse(bytes);

			return bytes;
		}

		public static byte[] GetBytes(string source)
		{
			return GetBytes(source, 16);
		}

		public static byte[] GetBytes(string source, int fromBase)
		{
			List<byte> bytes = new List<byte>();

			for (int i = 0; i < source.Length / 2; i++)
				bytes.Add(Convert.ToByte(source.Substring(i * 2, 2), fromBase));

			return bytes.ToArray();
		}

		public static string Decode7bit(string source, int length)
		{
			byte[] bytes = GetInvertBytes(source);

			string binary = string.Empty;

			foreach (byte b in bytes)
				binary += Convert.ToString(b, 2).PadLeft(8, '0');

			binary = binary.PadRight(length * 7, '0');

			string result = string.Empty;

			for (int i = 1; i <= length; i++)
				result += (char) Convert.ToByte(binary.Substring(binary.Length - i * 7, 7), 2);

			return result.Replace('\x0', '\x40');
		}

		public static string Decode8bit(string source, int length)
		{
			byte[] bytes = GetBytes(source.Substring(0, length * 2));

			//or ASCII?
			return Encoding.UTF8.GetString(bytes);
		}


		public static string DecodeUCS2(string source, int length)
		{
			byte[] bytes = GetBytes(source.Substring(0, length * 2));

			return Encoding.BigEndianUnicode.GetString(bytes);
		}

		public static byte[] EncodeUCS2(string s)
		{
			return Encoding.BigEndianUnicode.GetBytes(s);
		}

		public static string ReverseBits(string source)
		{
			return ReverseBits(source, source.Length);
		}

		public static string ReverseBits(string source, int length)
		{
			string result = string.Empty;

			for (int i = 0; i < length; i++)
				result = result.Insert(i % 2 == 0 ? i : i - 1, source[i].ToString());

			return result;
		}

		public static byte PeekByte(string source)
		{
			return PeekByte(source, 0);
		}

		public static byte PeekByte(string source, int byteIndex)
		{
			return Convert.ToByte(source.Substring(byteIndex * 2, 2), 16);
		}

		public static byte PopByte(ref string source)
		{
			byte b = Convert.ToByte(source.Substring(0, 2), 16);

			source = source.Substring(2);

			return b;
		}

		public static byte[] PopBytes(ref string source, int length)
		{
			string bytes = source.Substring(0, length * 2);
			
			source = source.Substring(length * 2);

			return GetBytes(bytes);
		}

		public static DateTime PopDate(ref string source)
		{
			byte[] bytes = GetBytes(ReverseBits(source.Substring(0, 12)), 10);

			source = source.Substring(14);

			return new DateTime(2000 + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5]);
		}

		public static string PopPhoneNumber(ref string source)
		{
			int numberLength = PopByte(ref source);

			if ((numberLength = numberLength + 2) == 2)
				return string.Empty;

			return PopAddress(ref source, numberLength + (numberLength % 2));
		}

		public static string PopServiceCenterAddress(ref string source)
		{
			int addressLength = PopByte(ref source);

			if ((addressLength = addressLength * 2) == 0)
				return string.Empty;

			return PopAddress(ref source, addressLength);
		}

		public static string PopAddress(ref string source, int length)
		{
			string address = source.Substring(0, length);

			source = source.Substring(address.Length);

			byte addressType = PopByte(ref address);

			address = ReverseBits(address).Trim('F');

			if (0x09 == addressType >> 4)
				address = "+" + address;

			return address;
		}

		public static SMSType GetSMSType(string source)
        {
			byte scaLength = PeekByte(source);
			byte pduType = PeekByte(source, scaLength + 1);

			byte smsType = (byte) ((pduType & 3) >> 1);

			if (!Enum.IsDefined(typeof(SMSType), (int) smsType))
				throw new UnknownSMSTypeException(pduType);

			return (SMSType) smsType;
        }

		public static void Fetch(SMSBase sms, ref string source)
		{
			sms._serviceCenterNumber = PopServiceCenterAddress(ref source);
			
			sms._pduType = PopByte(ref source);

			System.Collections.BitArray bits = new System.Collections.BitArray(new byte[] { sms._pduType });

			sms.ReplyPathExists = bits[7];
			sms.UserDataStartsWithHeader = bits[6];
			sms.StatusReportIndication = bits[5];

			sms.ValidityPeriodFormat = (ValidityPeriodFormat) (sms._pduType & 0x18);
			sms.Direction = (SMSDirection) (sms._pduType & 1);
		}

		#endregion

		#region Public Statics (Push)

		public static string EncodePhoneNumber(string phoneNumber)
		{
			bool isInternational = phoneNumber.StartsWith("+");

			if (isInternational)
				phoneNumber = phoneNumber.Remove(0, 1);

			int header = (phoneNumber.Length << 8) + 0x81 | (isInternational ? 0x10 : 0x20);

			if (phoneNumber.Length % 2 == 1)
				phoneNumber = phoneNumber.PadRight(phoneNumber.Length + 1, 'F');

			phoneNumber = ReverseBits(phoneNumber);

			return Convert.ToString(header, 16).PadLeft(4, '0') + phoneNumber;
		}

		#endregion

		#region Publics

		public virtual void ComposePDUType()
		{
			_pduType = (byte) Direction;
			_pduType = (byte) (_pduType | (int) ValidityPeriodFormat);

			if (StatusReportIndication)
				_pduType = (byte) (_pduType | 0x20);
		}

		#endregion

		#region Members
		//protected SMSType _type;
		protected byte _pduType;
		protected string _serviceCenterNumber;

		#region PDU type (first octet) data
		//Reply path. Parameter indicating that reply path exists.
		protected bool _replyPathExists;
		//User data header indicator. This bit is set to 1 if the User Data field starts with a header. (EMS?)
		protected bool _userDataStartsWithHeader;
		//Status report indication. This bit is set to 1 if a status report is going to be returned to the SME.
		protected bool _statusReportIndication;
		//Validity Period Format
		protected ValidityPeriodFormat _validityPeriodFormat = ValidityPeriodFormat.FieldNotPresent;
		//Message type indication
		//First bit
		protected SMSDirection _direction;
		#endregion

		#endregion

		#region Proreties
		public string ServiceCenterNumber
		{
			get { return _serviceCenterNumber; }
			set { _serviceCenterNumber = value; }
		}

		public bool ReplyPathExists
		{
			get { return _replyPathExists; }
			set { _replyPathExists = value; }
		}

		public bool UserDataStartsWithHeader
		{
			get { return _userDataStartsWithHeader; }
			set { _userDataStartsWithHeader = value; }
		}

		public bool StatusReportIndication
		{
			get { return _statusReportIndication; }
			set { _statusReportIndication = value; }
		}

		public ValidityPeriodFormat ValidityPeriodFormat
		{
			get { return _validityPeriodFormat; }
			set { _validityPeriodFormat = value; }
		}

		public SMSDirection Direction
		{
			get { return _direction; }
			set { _direction = value; }
		}

		public abstract SMSType Type { get; }
		#endregion

    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -