Php/XtremUnsplit
From Php-Classes
Contents |
[edit] XtremUnsplit
[edit] description
Voici une classe php et le code associé pour décoder les fichiers splités avec XtremSplit
- ce script ne vérifie pas l'intégrité des fichiers avec les md5sum, veuillez utiliser par2 pour cela,
- ce script essaie de determiner au mieux si le fichier est bien au format XtremSplit, auquel cas il le reconstitue.
[edit] Utilisation
php -q xtremUnplit.php data.001.xtm
remplacer data par le nom de votre fichier. Sur plateforme ubunutu, vous devez installer php avec cette commande :
sudo apt-get install php5-cli
[edit] Restriction
ne fonctionne qu'avec les fichiers sources dans le répertoire courant ; ceci ne fonctionnera pas :
php -q xtremUnplit.php temp_dir/data.001.xtm
[edit] source code
<?php error_reporting(E_ALL); /** * author : Marc Quinton / march 2007. * * this script is used to unsplit file from xtremsplit software. * more information about this file format at : * * http://xtremsplit.free.fr/?page=windows&page2=faq (header) */ define('HEADER_SIZE', 104); class XtremSplit{ protected $fd; protected $file; protected $header; public function __construct(){ $this->header = null; } public function info($file){ if(!file_exists($file)) return false; $this->fd = fopen($file, 'r'); $this->header = $this->get_header(); fclose($this->fd); if(!$this->is_xtrem_file()){ echo "$file is not an extrem-split file\n"; exit(1); } echo "num files = " . $this->num_files() . "\n"; echo "filename = " . $this->filename() . "\n"; echo "prog = " . $this->program_name() . "\n"; echo "version = " . $this->version() . "\n"; echo "file size = " . $this->file_size() . "\n"; if($this->hash_enabled()) echo "hash enabled\n"; else echo "hash not enabled\n"; printf("prog : %s\n", $this->header_read_string_by_len(0)); } # ---------------------------------- XtremSplit header reading functions ------------------------------------------- /** * the most basic header reading function : reads $bytes at $pos */ protected function header_read_bytes($pos, $bytes){ $data = ; for($i=0 ; $i<$bytes ; $i++) $data .= $this->header[$pos++]; return $data; } /** * read 1 char at $pos and return as unsigned char (int value) */ protected function header_read_unsigned_char($pos){ $data = unpack('C', $this->header_read_bytes($pos, 1)); return $data[1]; } /** * unused ; read a string at $pos and return when read "\n" char */ protected function header_read_string($pos, $terminator="\n"){ $data = ; while($this->header[$pos] != $terminator) $data .= $this->header[$pos++]; return $data; } /** * read a string in header ; $pos is strlen ; value is after strlen ($pos+1) * return a string */ protected function header_read_string_by_len($pos){ $len = $this->header_read_unsigned_char($pos++); return $this->header_read_bytes($pos, $len); } # ------------------------------------- XtremSplit header info ------------------------------------------------- /** * try to determine if this is an XtremSplit file ; use this before doing complexe reading operations. */ protected function is_xtrem_file(){ $name = trim($this->program_name()); $len = $this->header_read_unsigned_char(0); if(strcasecmp($this->program_name(), 'Xtmsplit') != 0) return false; if($len != strlen($name)) return false; return true; } /** * number of files used to split original file */ public function num_files(){ $value = unpack('L', $this->header_read_bytes(92, 4)); return $value[1]; } /** * size of original file (can't read 8 bytes integers with php/unpack, so return only 4 bytes) */ public function file_size(){ $v1 = unpack('N', $this->header_read_bytes(96, 4)); # don't know how to unpack 8 bytes number # $v2 = unpack('N', $this->header_read_bytes(100, 4)); # don't know how to unpack 8 bytes number return $v1[1]; # not correct } /** * does XtremSplit contains md5sum hash at the end of last file. */ public function hash_enabled(){ $enabled = $this->header_read_unsigned_char(91); return $enabled == '1'; } /** * version of xtremsplit that generated this header file */ public function version(){ return trim($this->header_read_bytes(22, 4)); } /** * program that generated this header file. */ public function program_name(){ return $this->header_read_string_by_len(0); } /** * original filename before spliting */ public function filename(){ return $this->header_read_string_by_len(40); } /** * main method for unspliting files. */ public function unsplit($file){ $this->fd = fopen($file, 'r'); $this->header = $this->get_header(); fclose($this->fd); echo "unspliting to source file $file\n"; $orig_file = $this->filename(); $count = $this->num_files(); $files = array(); for($i=0 ; $i< $count ; $i++){ $files[] = sprintf('%s.%03d.xtm', $orig_file, $i+1); } if(file_exists($this->filename())) unlink($this->filename()); $out = fopen($this->filename(), 'w+'); foreach($files as $key=>$f){ echo "unspliting file $f ...\n"; if(!file_exists($f)) throw new Exception("file not found : $f"); $fd = fopen($f, 'r'); if($key == 0) $header = fread($fd, HEADER_SIZE); # skip header; while(!feof($fd)){ $data = fread($fd, 1024*10); fwrite($out, $data); } fclose($fd); } # remove hashes from end of file if hash is enabled. if($this->hash_enabled()){ $size = filesize($this->filename()) - $count*32; ftruncate($out, $size); } fclose($out); } /** * read header from $this->fd ; need to call this method before trying to get header information. */ protected function get_header($size = HEADER_SIZE){ $data = fread($this->fd, $size); return $data; } } $args = $_SERVER['argv']; if(count($args) == 2){ $file = $args[1]; $xtrem = new XtremSplit(); # $xtrem->info($file); $xtrem->unsplit($file); } ?>
[edit] links
- XtremSplit : http://xtremsplit.free.fr/ - l'original ; fonctionne sous windows, mais on attend encore la version linux malgrès la présence du [manuel]
- tuxtremsplit : http://zedmatrix2.free.fr/tuxtremsplit/ - un décodeur pour linux, en C avec interface GTK.
- xtmsplit : http://www.software.caelistis.be/xtmsplit-0.2.tar.gz : un encodeur, [décodeur] en C++
- XTremSplitQt : http://lmamat08.free.fr/XTremSplit/ - une interface Qt pour XtremSplit

