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

📄 mmsdecoder.php

📁 mms decoder,彩信解码程序
💻 PHP
📖 第 1 页 / 共 2 页
字号:
<?php
// Version 0.77 //

/**
 * Copyright (C) 2004 Jonatan Heyman
 *
 * This file is part of the PHP application MMS Decoder.
 *
 * MMS Decoder is free software; you can redistribute it and/or
 * modify it under the terms of the Affero General Public License as
 * published by Affero, Inc.; either version 1 of the License, or
 * (at your option) any later version.
 *
 * MMS Decoder is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Affero General Public License for more details.
 *
 * You should have received a copy of the Affero General Public
 * License in the COPYING file that comes with The Affero Project; if
 * not, write to Affero, Inc., 510 Third Street, Suite 225, San
 * Francisco, CA 94107 USA. 
 */


define( "DEBUG", 0 );	// Print parseerrors? Print values while they are parsed? If you enable this, sending MMS from mobiles may not work. This is only for development purpose.


/*---------------------------------------------------*
 * Constants                                         *
 *                                                   *
 * http://wapforum.org/                              *
 * WAP-209-MMSEncapsulation-20020105-a               *
 * Table 8                                           *
 *                                                   *
 * The values are enconded using WSP 7bit encoding.  *
 * Read more about how to decode this here:          *
 * http://www.nowsms.com/discus/messages/12/3287.html*
 *                                                   *
 * Example from the above adress:                    *
 * 7Bit 0D =  0001101                                *
 * 8Bit 0D = 10001101 = 8D                           *
 *---------------------------------------------------*/
define( "BCC",			0x81 );
define( "CC",			0x82 );
define( "CONTENT_LOCATION",	0x83 );
define( "CONTENT_TYPE",		0x84 );
define( "DATE",			0x85 );
define( "DELIVERY_REPORT",	0x86 );
define( "DELIVERY_TIME",	0x87 );
define( "EXPIRY",		0x88 );
define( "FROM",			0x89 );
define( "MESSAGE_CLASS",	0x8A );
define( "MESSAGE_ID",		0x8B );
define( "MESSAGE_TYPE",		0x8C );
define( "MMS_VERSION",		0x8D );
define( "MESSAGE_SIZE",		0x8E );
define( "PRIORITY",		0x8F );
define( "READ_REPLY",		0x90 );
define( "REPORT_ALLOWED",	0x91 );
define( "RESPONSE_STATUS",	0x92 );
define( "RESPONSE_TEXT",	0x93 );
define( "SENDER_VISIBILITY",	0x94 );
define( "STATUS",		0x95 );
define( "SUBJECT",		0x96 );
define( "TO",			0x97 );
define( "TRANSACTION_ID",	0x98 );


/*--------------------------*
 * Array of header contents *
 *--------------------------*/
$mmsMessageTypes = array (
	0x80 => "m-send-req",
	0x81 => "m-send-conf",
	0x82 => "m-notification-ind",
	0x83 => "m-notifyresp-ind",
	0x84 => "m-retrieve-conf",
	0x85 => "m-acknowledge-ind",
	0x86 => "m-delivery-ind",
	0x00 => NULL
);

/*--------------------------*
 * Some other useful arrays *
 *--------------------------*/
$mmsYesNo = array(
	0x80 => 1,
	0x81 => 0,
	0x00 => NULL
);

$mmsPriority = array(
	0x80 => "Low",
	0x81 => "Normal",
	0x82 => "High",
	0x00 => NULL
);

$mmsMessageClass = array(
	0x80 => "Personal",
	0x81 => "Advertisement",
	0x82 => "Informational",
	0x83 => "Auto"
);

$mmsContentTypes = array(
	0x00 => '*/*',
	0x01 => 'text/*',
	0x02 => 'text/html',
	0x03 => 'text/plain',
	0x04 => 'text/x-hdml',
	0x05 => 'text/x-ttml',
	0x06 => 'text/x-vCalendar',
	0x07 => 'text/x-vCard',
	0x08 => 'text/vnd.wap.wml',
	0x09 => 'text/vnd.wap.wmlscript',
	0x0A => 'text/vnd.wap.wta-event',
	0x0B => 'multipart/*',
	0x0C => 'multipart/mixed',
	0x0D => 'multipart/form-data',
	0x0E => 'multipart/byterantes',
	0x0F => 'multipart/alternative',
	0x10 => 'application/*',
	0x11 => 'application/java-vm',
	0x12 => 'application/x-www-form-urlencoded',
	0x13 => 'application/x-hdmlc',
	0x14 => 'application/vnd.wap.wmlc',
	0x15 => 'application/vnd.wap.wmlscriptc',
	0x16 => 'application/vnd.wap.wta-eventc',
	0x17 => 'application/vnd.wap.uaprof',
	0x18 => 'application/vnd.wap.wtls-ca-certificate',
	0x19 => 'application/vnd.wap.wtls-user-certificate',
	0x1A => 'application/x-x509-ca-cert',
	0x1B => 'application/x-x509-user-cert',
	0x1C => 'image/*',
	0x1D => 'image/gif',
	0x1E => 'image/jpeg',
	0x1F => 'image/tiff',
	0x20 => 'image/png',
	0x21 => 'image/vnd.wap.wbmp',
	0x22 => 'application/vnd.wap.multipart.*',
	0x23 => 'application/vnd.wap.multipart.mixed',
	0x24 => 'application/vnd.wap.multipart.form-data',
	0x25 => 'application/vnd.wap.multipart.byteranges',
	0x26 => 'application/vnd.wap.multipart.alternative',
	0x27 => 'application/xml',
	0x28 => 'text/xml',
	0x29 => 'application/vnd.wap.wbxml',
	0x2A => 'application/x-x968-cross-cert',
	0x2B => 'application/x-x968-ca-cert',
	0x2C => 'application/x-x968-user-cert',
	0x2D => 'text/vnd.wap.si',
	0x2E => 'application/vnd.wap.sic',
	0x2F => 'text/vnd.wap.sl',
	0x30 => 'application/vnd.wap.slc',
	0x31 => 'text/vnd.wap.co',
	0x32 => 'application/vnd.wap.coc',
	0x33 => 'application/vnd.wap.multipart.related',
	0x34 => 'application/vnd.wap.sia',
	0x35 => 'text/vnd.wap.connectivity-xml',
	0x36 => 'application/vnd.wap.connectivity-wbxml',
	0x37 => 'application/pkcs7-mime',
	0x38 => 'application/vnd.wap.hashed-certificate',
	0x39 => 'application/vnd.wap.signed-certificate',
	0x3A => 'application/vnd.wap.cert-response',
	0x3B => 'application/xhtml+xml',
	0x3C => 'application/wml+xml',
	0x3D => 'text/css',
	0x3E => 'application/vnd.wap.mms-message',
	0x3F => 'application/vnd.wap.rollover-certificate',
	0x40 => 'application/vnd.wap.locc+wbxml',
	0x41 => 'application/vnd.wap.loc+xml',
	0x42 => 'application/vnd.syncml.dm+wbxml',
	0x43 => 'application/vnd.syncml.dm+xml',
	0x44 => 'application/vnd.syncml.notification',
	0x45 => 'application/vnd.wap.xhtml+xml',
	0x46 => 'application/vnd.wv.csp.cir',
	0x47 => 'application/vnd.oma.dd+xml',
	0x48 => 'application/vnd.oma.drm.message',
	0x49 => 'application/vnd.oma.drm.content',
	0x4A => 'application/vnd.oma.drm.rights+xml',
	0x4B => 'application/vnd.oma.drm.rights+wbxml'
);


/*-------------------------------*
 * The MMS header decoding class *
 *-------------------------------*/
class MMSDecoder {
	var $data;	// The unparsed MMS data in an array of the ascii numbers
	var $pos = 0;	// The current parsing position of the data array
	var $PARTS = array();
	
	// The parsed data will be saved in these variables
	var 
		$BCC, 
		$CC, 
		$CONTENTLOCATION, 
		$CONTENTTYPE, 
		$DATE, 
		$DELIVERYREPORT, 
		$DELIVERYTIME, 
		$EXPIRY, 
		$FROM, 
		$MESSAGECLASS, 
		$MESSAGEID, 
		$MESSAGETYPE, 
		$MMSVERSIONMAJOR, 
		$MMSVERSIONMINOR,
		$MESSAGESIZE, 
		$PRIORITY, 
		$READREPLY, 
		$REPORTALLOWED, 
		$RESPONSESTATUS, 
		$RESPONSETEXT, 
		$SENDERVISIBILITY, 
		$STATUS, 
		$SUBJECT, 
		$TO, 
		$TRANSACTIONID, 
		$MMSVERSIONRAW, 	// used for the m-send-conf (confirmation answer)
		$CONTENTTYPE_PARAMS;	// parameter-values for the MMS content-type
	
	
	
	// Constructor
	function MMSDecoder($data) {
		$this->data = array();
		
		// Save the data in an array containing the ascii numbers
		for ($i = 0; $i < strlen($data); $i++)
			$this->data[$i] = ord($data[$i]);
		
		// Reset position
		$this->pos = 0;
		
		// Reset variables
		$this->PARTS = array();
	}
	
	
	// This function is called when the data is to be parsed
	function parse() {
		// Reset position
		$this->pos = 0;
		
		// parse the header
		while ($this->parseHeader());
		
		// Header done, fetch parts, but make sure the header was parsed correctly
		if ($this->CONTENTTYPE == 'application/vnd.wap.multipart.related' || $this->CONTENTTYPE == 'application/vnd.wap.multipart.mixed')
			while ($this->parseParts());
		else
			return 0;
		
		return 1;
	}
	
	
	/*---------------------------------------------------*
	 * This function checks what kind of field is to be  *
	 * parsed at the moment                              *
	 *                                                   *
	 * If true is returned, the class will go on and     *
	 * and continue decode the header. If false, the     *
	 * class will end the header decoding.               *
	 *---------------------------------------------------*/
	function parseHeader() {
		// Some global variables used
		global $mmsMessageTypes, $mmsYesNo, $mmsPriority, $mmsMessageClass, $mmsContentTypes;
		
		if (!array_key_exists($this->pos, $this->data))
			return 0;
		
		switch ($this->data[$this->pos++]) {
			case BCC:
				$this->BCC = $this->parseEncodedStringValue();
				if (DEBUG) $this->debug("BCC", $this->BCC);
				break;
			case CC:
				$this->CC = $this->parseEncodedStringValue();
				if (DEBUG) $this->debug("CC", $this->CC);
				break;
			case CONTENT_LOCATION:
				$this->CONTENTLOCATION = $this->parseTextString();
				if (DEBUG) $this->debug("Content-location", $this->CONTENTLOCATION);
				break;
			case CONTENT_TYPE:
				if ($this->data[$this->pos] <= 31) { /* Content-general-form */
					$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)
						$this->CONTENTTYPE = $this->parseTextString();
					else {
						// we have Well-known-media; which is an integer
						$this->CONTENTTYPE = $mmsContentTypes[$this->parseIntegerValue()];
					}
				} elseif ($this->data[$this->pos] < 128) { /* Constrained-media - Extension-media*/
					$this->CONTENTTYPE = $this->parseTextString();
				} else /* Constrained-media - Short Integer*/
					$this->CONTENTTYPE = $mmsContentTypes[$this->parseShortInteger()];
				
				// Ok, now we have parsed the content-type of the message, let's see if there are any parameters
				while (!$noparams) {
					switch ($this->data[$this->pos]) {
						case 0x89: // Start, textstring
							$this->pos++;
							$this->parseTextString();
							break;
						case 0x8A: // type, constrained media
							$this->pos++;
							if ($this->data[$this->pos] < 128) { /* Constrained-media - Extension-media*/
								$this->pos++;
								$this->parseTextString();
							} else // Constraind-media Short Integer
								$this->CONTENTTYPE_PARAMS[type] = $this->parseShortInteger();   
							break;
						default:
							$noparams = 1;
							break;
					}
				}
				
				if (DEBUG) $this->debug("Content-type", $this->CONTENTTYPE);
				
				// content-type parsed, that means we have reached the end of the header
				return 0;
				
			case DATE: /* In seconds from 1970-01-01 00:00 GMT */
				$this->DATE = $this->parseLongInteger();
				if (DEBUG) $this->debug("Date", date("Y-m-d H:i:s", $this->DATE));
				break;
			case DELIVERY_REPORT:		/* Yes | No */
				$this->DELIVERYREPORT = $mmsYesNo[ $this->data[$this->pos++] ];
				if (DEBUG) $this->debug("Delivery-report", $this->DELIVERYREPORT);
				break;
			case DELIVERY_TIME:
				if (DEBUG) $this->debug("Delivery-time", $this->DELIVERYTIME);
				break;
			case EXPIRY:
				// not sure if this is right, but if I remeber right, it's the same format as date...
				$this->EXPIRY = parseLongInteger();
				if (DEBUG) $this->debug("Expiry", $this->EXPIRY);
				break;
			case FROM:
				$this->FROM = $this->parseEncodedStringValue();
				if (DEBUG) $this->debug("From", $this->FROM);
				break;
			case MESSAGE_CLASS:
				$this->MESSAGECLASS = $mmsMessageClass[ $this->parseMessageClassValue() ];
				if (DEBUG) $this->debug("Message-class", $this->MESSAGECLASS);
				break;
			case MESSAGE_ID:		/* Text string */
				$this->MESSAGEID = $this->parseTextString();
				if (DEBUG) $this->debug("Message-id", $this->MESSAGEID);
				break;
			case MESSAGE_TYPE:
				//$this->MESSAGETYPE = $mmsMessageTypes[ $this->data[$this->pos++] ];
				$this->MESSAGETYPE = $this->data[$this->pos++];
				
				// check that the message type is m-send-req
				if (!$this->MESSAGETYPE = 128)
					debug("Wrong type", "The message-type field is not 'm-send-req' (Octet 128)", 1);
				
				if (DEBUG) $this->debug("Message-type", $mmsMessageTypes[$this->MESSAGETYPE]);
				break;
			case MMS_VERSION:
				/*
				 * The version number (1.0) is encoded as a WSP short integer, which
				 * is a 7 bit value. 
				 * 
				 * The three most significant bits (001) are used to encode a major
				 * version number in the range 1-7. The four least significant
				 * bits (0000) contain a minor version number in the range 1-14. 
				 */
				$this->MMSVERSIONRAW = $this->data[$this->pos];
				$this->MMSVERSIONMAJOR = ($this->data[$this->pos] & 0x70) >> 4;
				$this->MMSVERSIONMINOR = ($this->data[$this->pos++] & 0x0F);
				
				if (DEBUG) $this->debug("MMS-version", $this->MMSVERSIONMAJOR . "." . $this->MMSVERSIONMINOR);
				break;
			case MESSAGE_SIZE:		/* Long integer */
				$this->MESSAGESIZE = $this->parseLongInteger();
				if (DEBUG) $this->debug("Message-size", $this->MESSAGESIZE);
				break;
			case PRIORITY:			/* Low | Normal | High */
				$this->PRIORITY = $mmsPriority[ $this->data[$this->pos++] ];
				if (DEBUG) $this->debug("Priority", $this->PRIORITY);
				break;
			case READ_REPLY:		/* Yes | No */
				$this->READREPLY = $mmsYesNo[ $this->data[$this->pos++] ];
				if (DEBUG) $this->debug("Read-reply", $this->READREPLY);
				break;
			case REPORT_ALLOWED:		/* Yes | No */
				$this->REPORTALLOWED = $mmsYesNo[ $this->data[$this->pos++] ];
				if (DEBUG) $this->debug("Report-allowed", $this->REPORTALLOWED);
				break;

⌨️ 快捷键说明

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