PHP Classes

File: ascii85.php

Recommend this page to a friend!
  Classes of Sam S   ASCII85   ascii85.php   Download  
File: ascii85.php
Role: Class source
Content type: text/plain
Description: the base class
Class: ASCII85
Encode and decode data using the ASCII85 algorithm
Author: By
Last change: updated comments
Date: 17 years ago
Size: 7,282 bytes
 

Contents

Class file image Download
<?php
/**
 * Adapted from the work of Paul Haahr, http://www.webcom.com/~haahr/
 * http://www.stillhq.com/cgi-bin/cvsweb/ascii85/
 *
*/
/**
 * @package ASCII85
 * @example /ascii85example.php Example usage of this class.
 * @category Numbers
 * @author Sam Shull <samshull@samshull.com>
 * @copyright Copyright (c) 2007, Sam Shull
 * @license http://www.samshull.com/bsdlicense.txt BSD License
 * @link http://samshull.com/ascii85example.php
 * @version 0.9
 * @access public
*/
class ASCII85{
/**
 * Line width for splitting
 *
 * @var integer
 * @access protected
 */
 
var $width = 72;
/**
 * Position within the line
 *
 * @var integer
 * @access protected
 */
 
var $pos = 0;
/**
 * Unsigned long being manipulated
 *
 * @var string
 * @access protected
 */
 
var $tuple = "0";
/**
 * Number of bytes being manipulated
 *
 * @var integer
 * @access protected
 */
 
var $count = 0;
/**
 * Output
 *
 * @var string
 * @access protected
 */
 
var $out = "";
/**
 * Power of 85 multiplier
 *
 * @var array
 * @access protected
 */
 
var $pow85;
/**
 * Error
 *
 * @var string
 * @access public
 */
 
var $error;
/**
 * For storing unpacked bytes
 *
 * @var array
 * @access protected
 */
 
var $array = array();
/**
 * Position within byte array
 *
 * @var integer
 * @access protected
 */
 
var $i = 1;

/**
 * Method: encode
 * Primary encoding method, one argument, the string that is to be encoded
 * @param string $string
 * @return string
**/
function encode($string){
  
$this->error = "";
  
$this->out = "<~";
   
$this->pos = 2;
   
     
$array = unpack("C*",$string);
     
//print_r($array);
     
for($i=1;$i<=count($array);$i++){
       
$this->put85($array[$i]);
      }
     
   if (
$this->count > 0)
       
$this->encode85(false);
    if (
$this->pos + 2 > $this->width)
       
$this->out.="\n";
   
$this->out.="~>\n";
      if(
$this->error){
        return
$this->error;
      }else{
        return
$this->out;
      }
}

/**
 * Method: encode85 - if PHP5 mark as private or protected
 * Method used to convert an unsigned long to ASCII characters
 * One parameter bool increase the count by one when adding
 * encoded characters to output string
 * @param bool $tru default:true
**/
function encode85($tru=true) {
   
$s = array();
   
$i = 5;
     while (--
$i >= 0){
       
$s[$i] = (int)bcmod($this->tuple,"85");
       
$this->tuple = bcdiv($this->tuple,"85");
    }
   
//print_r($s);
   
$f = $tru ? 1 : 0;
     for(
$i=0;$i<=$this->count+$f;$i++){
       
$this->out .= chr(($s[$i] + ord('!')));
        if (
$this->pos++ >= $this->width) {
           
$this->pos = 0;
           
$this->out.="\n";
        }
    }
}
/**
 * Method: put85 - if PHP5 mark as private or protected
 * Method is passed each char of the string to be encoded and adds it
 * to an unsigned long for conversion by encode85
 * @param decimal $c
**/
function put85($c) {
    switch (
$this->count) {
    case
0: $this->tuple = bcadd($this->lshift($c,24),$this->tuple);
           
$this->count++;
            break;
    case
1: $this->tuple = bcadd($this->tuple,((string)($c << 16)));
            
$this->count++;
             break;
    case
2: $this->tuple = bcadd($this->tuple,((string)($c << 8)));
           
$this->count++;
            break;
    case
3:
       
$this->tuple = bcadd($this->tuple,((string)$c));
        if (
$this->tuple == 0) {
           
$this->out.='z';
            if (
$this->pos++ >= $this->width) {
               
$this->pos = 0;
               
$this->out.="\n";
            }
        } else {
           
$this->encode85();
        }
       
$this->tuple = "0";
       
$this->count = 0;
        break;
    }
}
/**
 * Method: decode
 * Primary method used to decode an encoded string, one parameter an encoded string
 * Breaks apart string for encoding and returns
 * @param string $string
 * @return string
**/
 
function decode($string){
     
$this->error = "";
     
$this->out = "";
     
$this->count = 0;
     
$this->pow85 = array((85*85*85*85), (85*85*85), (85*85), 85, 1);
     
$string=preg_replace("/^<~/isx","",$string);
     
$this->array = str_split($string);
      while(
$this->i < count($this->array)){
       
$this->decode85(current($this->array));
       
next($this->array);
       
$this->i++;
      }
      if(
$this->error){
        return
$this->error;
      }else{
        return
$this->out;
      }
  }
/**
 * Method: wput - if PHP5 mark as private or protected
 * Used to pack the output codes, one parameter number of bytes to output
 * @param int $bytes
**/
 
function wput($bytes) {
    switch (
$bytes) {
    case
4:
       
$this->out.=pack("C",$this->rshift($this->tuple,24));
       
$this->out.=pack("C",$this->rshift($this->tuple,16));
       
$this->out.=pack("C",$this->rshift($this->tuple,8));
       
$this->out.=pack("C",((float)$this->tuple));
        break;
    case
3:
       
$this->out.=pack("C",$this->rshift($this->tuple,24));
       
$this->out.=pack("C",$this->rshift($this->tuple,16));
       
$this->out.=pack("C",$this->rshift($this->tuple,8));
        break;
    case
2:
       
$this->out.=pack("C",$this->rshift($this->tuple,24));
       
$this->out.=pack("C",$this->rshift($this->tuple,16));
        break;
    case
1:
       
$this->out.=pack("C",$this->rshift($this->tuple,24));
        break;
    }
   
//$this->tuple = "0";
 
}
/**
 * Method: decode85 - if PHP5 mark as private or protected
 * Used to decode the chars and add them up in an unsigned long
 * to be encoded, one paramater char to be added
 * @param char $c
**/
 
function decode85($c) {
    switch (
$c) {
        case
'z':
            if (
$this->count != 0) {
               
$this->error.="\n: z inside ascii85 5-tuple";
                return;
            }
           
$this->out.=pack("C",0x00);
           
$this->out.=pack("C",0x00);
           
$this->out.=pack("C",0x00);
           
$this->out.=pack("C",0x00);
            break;
        case
'~':
           
$c = next($this->array);
            if (
$c == '>') {
                if (
$this->count > 0) {
                   
$this->count--;
                   
$this->tuple = bcadd($this->tuple,$this->pow85[$this->count]);
                   
$this->wput($this->count);
                }
                return;
            }
           
$this->error.="\n: ~ without > in ascii85 section";
            return;
        case
"\n": case "\r": case "\t": case " ":
        case
"\0": case "\f": case "\b": case 0177:
            break;
        default:
           
//echo (ord($c)-ord('!'))."\n";
           
if (ord($c) < ord('!') || ord($c) > ord('u')) {
               
$this->error.="\nBad character in ascii85 region: ".current($this->array)." ".$this->i;
               
//return;
           
}
           
$this->tuple = bcadd($this->tuple,bcmul((ord($c)-ord('!')),$this->pow85[$this->count]));
           
$this->count++;
            if (
$this->count == 5) {
               
$this->wput(4);
               
$this->count = 0;
               
$this->tuple = "0";
            }
            break;
        }
  }
/**
 * Method: lshift - if PHP5 mark as private or protected
 * Used to allow class to deal with unsigned longs, bitwise left shift
 * Two parameters, number to be shifted, and how much to shift
 * @param int|string $n
 * @param int $b
 * @return string
**/
 
function lshift($n,$b){
   for(
$t=0;$t<$b;$t++){
     
$n = bcmul($n,"2");
   }
   return ((string)
$n);
  }
/**
 * Method: rshift - if PHP5 mark as private or protected
 * Used to allow class to deal with unsigned longs, bitwise right shift
 * Two parameters, number to be shifted, and how much to shift
 * @param int $n
 * @param int $b
 * @return int
 */
 
function rshift($n,$b){
   for(
$t=0;$t<$b;$t++){
     
$n = bcdiv($n,"2");
   }
   return ((int)
$n);
  }
}

?>