如何将一个.jpeg文件分成几个原始文件?

时间:2014-09-18 08:30:51

标签: bash jpeg

所以,我正在搞乱bash,并且意外地将几个具有.txt扩展名的.jpg文件合并到一个.jpg中。我写的愚蠢是

mv ./*.txt .jpg

关于如何撤消它的任何想法?创建的文件的大小与所有合并的其他文件的大小兼容,所以我猜它就在那里,但是无法想出如何分离二进制文件......

(是的,为什么我这样做呢?谁知道呢)

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

JPEG文件以d8ff作为JPEG标记开头。所以,十六进制转储你的文件和grep d8ff

 od -x yourTextfile.txt | grep d8ff

然后获取字节偏移量,并使用dd提取文件。因此,如果在地址2048处看到JPEG标记,请执行以下操作:

dd if=yourTextFile bs=1 iseek=2048 > file1.jpg

您需要将blocksize设置为1(bs=1),以使偏移量以字节为单位而不是512字节块。有些dd版本比skip更喜欢iseek

注意:您将在JPEG文件的末尾获得无关的垃圾,但大多数图片编辑都会忽略它。

<强>更新

这是一种在Perl中恢复文件的稍微漂亮的方法...

#!/usr/bin/perl
use strict;
use warnings;

my $contents;
my $i=0;

# Slurp entire file
{
  local $/ = undef;
  open FILE, "file.txt" or die "Couldn't open file: $!";
  $contents = <FILE>;
  close FILE;
}
while((my $offset=index($contents,"\xff\xd8"))!=-1){
    my $filename=sprintf("recovered_%d.jpg",$i++);
    printf "Recovering at offset: $offset into file: $filename\n";
    open(OUTFILE,">$filename");
    print OUTFILE substr($contents,$offset,10000000);
    close(OUTFILE);
    substr($contents,$offset,2)="\x00\x00";   # Overwrite this header so we find another next time
}

Uglier shell版本

你可以用这样的代码编写代码 - 快速而脏的代码警告!!!

#!/bin/bash
file=file.txt       # Edit with the name of your text file with all JPEGs in it
n=0
od -Ad -b "$file" | \
   awk '/377 330 377 340/ {for(i=2;i<NF-4;i++)
                              if($i=="377" && $(i+1)=="330" && $(i+2)=="377" && $(i+3)=="340")
                                print $1+i-2
                          }' | \
   while read offset; do
      name="recovered_${n}.jpg"
      echo Possible JPEG at offset $offset - recovering following 10MB as $name
      dd if="$file" of="$name" bs=1 iseek=$offset count=10000000
      ((n++))
   done

如果你运气不好,图片的标题可能跨越od输出的两行,在这种情况下,377 330 377 340不会全部在同一行和脚本上不会找到那个图像。我建议您运行脚本一次并将所有恢复的文件复制到另一个目录(以保存它们)然后再次运行它,而不是在文件的开头添加4个或更多字节以强制执行将整个JPEG签名放到下一行,如下所示:

(echo spacer; cat file.txt ) > file2.txt

然后再次运行脚本,但这次是file2.txt