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

📄 mmsdecoder.php

📁 mms decoder,彩信解码程序
💻 PHP
📖 第 1 页 / 共 2 页
字号:
			case RESPONSE_STATUS:
				$this->RESPONSESTATUS = $this->data[$this->pos++];
				if (DEBUG) $this->debug("Response-status", $this->RESPONSESTATUS);
				break;
			case RESPONSE_TEXT:		/* Encoded string value */
				$this->RESPONSETEXT = $this->parseEncodedStringValue();
				if (DEBUG) $this->debug("Response-text", $this->RESPONSETEXT);
				break;
			case SENDER_VISIBILITY:		/* Hide | show */
				$this->SENDERVISIBILITY = $mmsYesNo[ $this->data[$this->pos++] ];
				if (DEBUG) $this->debug("Sender-visibility", $this->SENDERVISIBILITY);
				break;
			case STATUS:
				$this->STATUS = $this->data[$this->pos++];
				if (DEBUG) $this->debug("Status", $this->STATUS);
				break;
			case SUBJECT:
				$this->SUBJECT = $this->parseEncodedStringValue();
				if (DEBUG) $this->debug("Subject", $this->SUBJECT);
				break;
			case TO:
				$this->TO = $this->parseEncodedStringValue();
				if (DEBUG) $this->debug("To", $this->TO);
				break;
			case TRANSACTION_ID:
				$this->TRANSACTIONID = $this->parseTextString();
				if (DEBUG) $this->debug("Transaction-id", $this->TRANSACTIONID);
				break;
			default:
				if ($this->data[$this->pos - 1] > 127) 
					$this->debug("Parse error", "Unknown field (" . $this->data[$pos-1] . ")!", $this->pos-1);
				else
					debug("Parse error:", "Value encountered when expecting field!", $this->pos);
				break;
		}
		
		return true;
	}
	
	/*---------------------------------------------------------------------*
	 * Function called after header has been parsed. This function fetches *
	 * the different parts in the MMS. Returns true until it encounter end *
	 * of data.                                                            *
	 *---------------------------------------------------------------------*/
	function parseParts() {
		global $mmsContentTypes; // for parsing the contenttypes
		
		if (!array_key_exists($this->pos, $this->data))
			return 0;
		
		// get number of parts
		$count = $this->parseUint();
		
		if (DEBUG) $this->debug("MMS parts", $count);
		
		for ($i = 0; $i < $count; $i++) {
			// new part, so clear the old data and header
			$data = "";
			$header = "";
			unset($ctype);
			
			// get header and data length
			$headerlen = $this->parseUint();
			$datalen = $this->parseUint();
			
			
			/* PARSE CONTENT-TYPE */
			// this is actually the same structure as in the MMS content-type
			// so maybe we should make this in a better way, but for now, I'll
			// just cut n paste
			
			// right now I just save the position in the MMS data array before I parse
			// the content-type, to be able to roll back after it has been parsed beacause
			// the headerlen includes both the content-type and the header
			// TODO: this is just a fast hack and shoul be done in a more proper way
			$ctypepos = $this->pos;
			
			if ($this->data[$this->pos] <= 31) { /* Content-general-form */
				// the value follows after the current byte and is "current byte" long
				$len = $this->parseValueLength();
				
				// check if next byte is in range of 32-127. Then we have a Extension-media which is a textstring
				if ($this->data[$this->pos] > 31 && $this->data[$this->pos] < 128)
					$ctype = $this->parseTextString();
				else {
					// we have Well-known-media; which is an integer
					$ctype = $mmsContentTypes[$this->parseIntegerValue()];
				}
			} elseif ($this->data[$this->pos] < 128) { /* Constrained-media - Extension-media*/
				//$this->pos++;
				$ctype = $this->parseTextString();
			} else /* Constrained-media - Short Integer */
				$ctype = $mmsContentTypes[$this->parseShortInteger()];
			
			// roll back position so it's just before the content-type again
			$this->pos = $ctypepos;
			/* END OF CONTENT TYPE */
			
			
			// Read header. Actually, we don't do anything with this yet.. just skipping it (note that the content-type is included in the header)
			for ($j = 0; $j < $headerlen; $j++)
				$header .= chr($this->data[$this->pos++]);
			
			// read data
			for ($j = 0; $j < $datalen; $j++)
				$data .= chr($this->data[$this->pos++]);
			
			if (DEBUG) $this->debug("Part ($i):headerlen", $headerlen);
			if (DEBUG) $this->debug("Part ($i):datalen", $datalen);
			if (DEBUG) $this->debug("Part ($i):content-type", $ctype);
			//if (DEBUG) $this->debug("Part ($i):data", $data); // I've commented this one, to get a cleaner debug
			
			$this->PARTS[] = new MMSPart($headerlen, $datalen, $ctype, $header, $data);
		}
		
		return false;
	}
	
	/*-------------------------------------------------------------------*
	 * Parse message-class                                               *
	 * message-class-value = Class-identifier | Token-text               *
	 * Class-idetifier = Personal | Advertisement | Informational | Auto *
	 *-------------------------------------------------------------------*/
	function parseMessageClassValue() {
		if ($this->data[$this->pos] > 127) {
			// the byte is one of these 128=personal, 129=advertisement, 130=informational, 131=auto
			return $this->data[$this->pos++];
		} else
			return $this->parseTextString();
	}
	
	/*----------------------------------------------------------------*
	 * Parse Text-string                                              *
	 * text-string = [Quote <Octet 127>] text [End-string <Octet 00>] *
	 *----------------------------------------------------------------*/
	function parseTextString() {
		// Remove quote
		if ($this->data[$this->pos] == 0x7F)
			$this->pos++;
		
		while ($this->data[$this->pos])
			$str .= chr($this->data[$this->pos++]);
		
		$this->pos++;
		
		return $str;
	}
	
	
	/*------------------------------------------------------------------------*
	 * Parse Encoded-string-value                                             *
	 *                                                                        *
	 * Encoded-string-value = Text-string | Value-length Char-set Text-string *
	 *                                                                        *
	 *------------------------------------------------------------------------*/
	function parseEncodedStringValue() {
		if ($this->data[$this->pos] < 32) {
			$len = $this->parseValueLength();
			
			$this->pos++;
			
			for ($i = 0; $i < $len-1; $i++)
				$str .= chr( $this->data[$this->pos++] );
			return $str;
		} else
			return $this->parseTextString();
	}
	
	
	/*--------------------------------------------------------------------------------*
	 * Parse Value-length                                                             *
	 * Value-length = Short-length<Octet 0-30> | Length-quote<Octet 31> Length<Uint>  *
	 *                                                                                *
	 * A list of content-types of a MMS message can be found here:                    *
	 * http://www.wapforum.org/wina/wsp-content-type.htm                              *
	 *--------------------------------------------------------------------------------*/
	function parseValueLength() {
		if ($this->data[$this->pos] < 31) {
			// it's a short-length
			return $this->data[$this->pos++];
		} elseif ($this->data[$this->pos] == 31) {
			// got the quote, length is an Uint
			$this->pos++;
			return $this->parseUint();
		} else {
			// uh, oh... houston, we got a problem
			die("Parse error: Short-length-octet (" . $this->data[$this->pos] . ") > 31 in Value-length at offset " . $this->pos . "!\n");
		}
	}
	
	
	/*--------------------------------------------------------------------------*
	 * Parse Long-integer                                                       *
	 * Long-integer = Short-length<Octet 0-30> Multi-octet-integer<1*30 Octets> *
	 *--------------------------------------------------------------------------*/
	function parseLongInteger() {
		// Get the number of octets which the long-integer is stored in
		$octetcount = $this->data[$this->pos++];
		
		// Error checking
		if ($octetcount > 30)
			die("Parse error: Short-length-octet (" . $this->data[$this->pos-1] . ") > 30 in Long-integer at offset " . $this->pos-1 . "!\n");
		
		// Get the long-integer
		for ($i = 0; $i < $octetcount; $i++) {
			$longint = $longint << 8;
			$longint += $this->data[$this->pos++];
		}
		
		return $longint;
	}
	
	
	/*------------------------------------------------------------------------*
	 * Parse Short-integer                                                    *
	 * Short-integer = OCTET                                                  *
	 * Integers in range 0-127 shall be encoded as a one octet value with the *
	 * most significant bit set to one, and the value in the remaining 7 bits *
	 *------------------------------------------------------------------------*/
	function parseShortInteger() {
		return $this->data[$this->pos++] & 0x7F;
	}
	
	
	/*-------------------------------------------------------------*
	 * Parse Integer-value                                         *
	 * Integer-value = short-integer | long-integer                *
	 *                                                             *
	 * This function checks the value of the current byte and then *
	 * calls either parseLongInt() or parseShortInt() depending on *
	 * what value the current byte has                             *
	 *-------------------------------------------------------------*/
	function parseIntegerValue() {
		if ($this->data[$this->pos] < 31)
			return $this->parseLongInteger();
		elseif ($this->data[$this->pos] > 127)
			return $this->parseShortInteger();
		else {
			$this->debug('ERROR', 'Not a IntegerValue field', $this->pos);
			$this->pos++;
			return 0;
		}
	}
	
	
	/*------------------------------------------------------------------*
	 * Parse Unsigned-integer                                           *
	 *                                                                  *
	 * The value is stored in the 7 last bits. If the first bit is set, *
	 * then the value continues into the next byte.                     *
	 *                                                                  *
	 * http://www.nowsms.com/discus/messages/12/522.html                *
	 *------------------------------------------------------------------*/
	function parseUint() {
		//if (!($this->data[$this->pos] & 0x80))
		//	return $this->data[$this->pos++] & 0x7F;
		
		while ($this->data[$this->pos] & 0x80) {
			// Shift the current value 7 steps
			$uint = $uint << 7;
			// Remove the first bit of the byte and add it to the current value
			$uint |= $this->data[$this->pos++] & 0x7F;
		}
		
		// Shift the current value 7 steps
		$uint = $uint << 7;
		// Remove the first bit of the byte and add it to the current value
		$uint |= $this->data[$this->pos++] & 0x7F;
		
		return $uint;
	}
	
	
	/**
	 * Send an OK response to the sender after the MMS has been recieved
	 * See "6.1.2. Send confirmation" in the wap-209-mmsencapsulation specification, on how this is constructed
	 */
	function confirm() {
		$pos = 0;
		
		$confirm[$pos++] = 0x8C; // message-type
		$confirm[$pos++] = 129;  // m-send-conf
		$confirm[$pos++] = 0x98; // transaction-id
		
		for ($i = 0; $i < strlen($this->TRANSACTIONID); $i++)
			$confirm[$i+$pos] = ord(substr($this->TRANSACTIONID, $i, 1));
		
		$pos += $i;
		
		$confirm[$pos++] = 0x00; // end of string
		$confirm[$pos++] = 0x8D; // version
		$confirm[$pos++] = 0x90; // 1.0
		$confirm[$pos++] = 0x92; // response-status
		$confirm[$pos]   = 128;  // OK
		
		// respond with the m-send-conf
		foreach ($confirm as $byte)
			echo chr($byte);
	}
	
	
	/*---------------------------------------*
	 * Function which outputs debug messages *
	 *---------------------------------------*/
	function debug($name, $str, $pos = -1, $errorlevel = 0) {
		if ($pos != -1)
			echo "<b>$name ($pos):</b> " . $str;
		else
			echo "<b>$name:</b> " . $str;
		
		echo "<br>\n";
		
		if ($errorlevel > 0)
			exit;
	}
	
	
	/*------------------------------------------*
	 * Function to output a part of the mmsdata *
	 * in HEX form, and mark one byte with a ^  *
	 *------------------------------------------*/
	function debughex($start, $count, $markstart = -1, $markcount = -1) {
		$hexcount = 0;
		$markstop = $markstart + $markcount;
		
		// set font so that the hex will be more readable
		echo '<br><font face="fixedsys" size="-1">';
		
		// loop thru data and print hex
		for ($i = $start; $i <= ($start+$count); $i++) {
			// fix marking
			if ($i == $markstart)
				echo '<font color="#ff0000">';
			if ($i == $markstop)
				echo '</font>';
			
			$hex = dechex($this->data[$i]);
			
			// add 0 before hex if needed
			if (strlen($hex) < 2)
				$hex = '0' . $hex;
			// add space
			$hex = ' ' . $hex;
			
			// check hexcount, wrap lines if needed etc
			if ($hexcount == 8)
				echo ' | ';
			elseif ($hexcount == 16) {
				echo '<br>';
				$hexcount = 0;
			}
			$hexcount++;
			
			echo $hex;
		}
		
		// som more html
		echo '</font><br><br>';
	}
}



/*---------------------------------------------------------------------*
 * The MMS part class                                                  *
 * An instance of this class contains the one parts of an MMS message. *
 *                                                                     *
 * The multipart type is formed as:                                    *
 * number |part1|part2|....|partN                                      *
 * where part# is formed by headerlen|datalen|contenttype|headers|data *
 *---------------------------------------------------------------------*/
class MMSPart {
	var $headerlen;
	var $header;
	var $DATALEN;
	var $CONTENTTYPE;
	var $DATA;
	
	/*----------------------------------*
	 * Constructor, just store the data *
	 *----------------------------------*/
	function MMSPart($headerlen, $datalen, $ctype, $header, $data) {
		$this->hpos = 0;
		$this->headerlen = $headerlen;
		$this->DATALEN = $datalen;
		$this->CONTENTTYPE = $ctype;
		$this->DATA = $data;
	}
	
	/*-------------------------------------*
	 * Save the data to a location on disk *
	 *-------------------------------------*/
	function save($filename) {
		$fp = fopen($filename, 'wb');
		fwrite($fp, $this->DATA);
		fclose($fp);
	}
}
?>

⌨️ 快捷键说明

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