2008-08-09 12 views
2

다른 것을 읽기 전에 original thread을 읽으십시오.xml 파일을 xfdl (base64-gzip)으로 인코딩하는 방법은 무엇입니까?

개요 : .xfdl 파일은 gzip으로 압축 된 .xml 파일로 base64로 인코딩되었습니다. .xfdl을 xml로 de-encode하여 수정할 수 있고 .xfdl 파일로 다시 인코딩 할 수 있습니다.

XFDL> xml.gz> XML> xml.gz> XFDL 나는 uudeview 사용하여 64 기수에서 .xfdl 파일을 해제 인코딩을 할 수 있었다

:

uudeview -i yourform.xfdl 

그런 다음 생성 된 XML은 100 % 읽을 수있는 멋진 보이는

gunzip -S "" <UNKNOWN.001> yourform-unpacked.xml 

을 gunzip을 사용하여 decommpressed. 다음 XML을 수정하지 않고, 내가 할 수 있어야한다 gzip을 사용하여 다시 압축 :

다음
gzip yourform-unpacked.xml 

가 기본-64에서 다시 인코딩 :

base64 -e yourform-unpacked.xml.gz yourform_reencoded.xfdl 

내 생각이 맞다면

, 원본 파일을 다시 인코딩 된 파일은 동일해야합니다. 그러나 yourform.xfdl과 yourform_reencoded.xfdl을 비교할 때 비교하면 일치하지 않습니다. 또한 원본 파일은 http://www.grants.gov/help/download_software.jsp#pureedge "> .xfdl 뷰어에서 볼 수 있으며 다시 인코딩 된 xfdl은 읽을 수 없다고 말합니다.

I 또한 uuenview를 base64로 다시 인코딩하려고 시도한 결과 동일한 결과가 나타납니다.

답변

0

gzip 알고리즘을 구현할 때마다 약간 씩 다르지만 여전히 올바른 파일과 원본 파일은 실행중인 파일과 다를 수 있습니다.

2

내가 아는 한 이미 압축 된 파일의 압축 수준을 찾을 수 없습니다. 파일을 압축하는 경우 압축 수준 - # 여기서 #은 1 - 9입니다. 1은 가장 빠른 압축이고 9는 가장 압축 된 파일입니다. 실제로 압축 된 파일을 추출 및 재 압축 된 파일과 비교해서는 안됩니다. 약간의 변형이 쉽게자를 수 있습니다. 귀하의 경우에는 gzip 된 버전 대신 base64로 인코딩 된 버전을 비교할 것입니다.

0

흥미 롭습니다. 그러나 그 차이는 그리 크지 않습니다. 새로 인코딩 된 파일은 더 길어서 이전과 이후의 바이너리를 비교할 때 데이터가 거의 일치하지 않습니다.

전 (첫 번째 세 줄)

H4sIAAAAAAAAC+19eZOiyNb3/34K3r4RT/WEU40ssvTtrhuIuKK44Bo3YoJdFAFZ3D79C6hVVhUq 
dsnUVN/qmIkSOLlwlt/JPCfJ/PGf9dwAlorj6pb58wv0LfcFUEzJknVT+/ml2uXuCSJP3kNf/vOQ 
+TEsFVkgoDfdn18mnmd/B8HVavWt5TsKI2vKN8magyENiH3Lf9kRfpd817PmF+jpiOhQRFZcXTMV 

(처음 세 줄) :

H4sICJ/YnEgAAzEyNDQ2LTExNjk2NzUueGZkbC54bWwA7D1pU+JK19/9FV2+H5wpByEhJMRH 
uRUgCMom4DBYt2oqkAZyDQlmQZ1f/3YSNqGzKT3oDH6RdE4vOXuf08vFP88TFcygYSq6dnlM 
naWOAdQGuqxoo8vjSruRyGYzfII6/id3dPGjVKwCBK+Zl8djy5qeJ5NPT09nTduAojyCZwN9 

당신은 그 그것의 대혼란 후, H4SI 일치 최대를 볼 수 있듯이.

+0

정확히 동일한 gzip 구현을 사용하지 않으면 H4sI가 같을 것이라고 기대할 수 있습니다. "Pandemonium"은 정상입니다 :-) –

1

당신은 XFDL 파일의 시작 부분에 다음 줄을 추가해야합니다 :

당신이 base64로 인코딩 된 파일을 생성 한 후에 application/vnd.xfdl; content-encoding="base64-gzip"

는, 텍스트 편집기에서 열고 붙여 넣기 첫 줄에 위의 줄. base64로 묶인 블록이 두 번째 라인의 시작 부분에서 시작하는지 확인하십시오.

저장하고 뷰어에서 사용해보십시오! 여전히 작동하지 않는다면 XML에 대한 변경으로 인해 일부 방식으로 비준수가 될 수 있습니다. 이 경우 XML을 수정 한 후 gzip 및 base64로 인코딩하기 전에 .xfdl 파일 확장명으로 저장하고 뷰어 도구로 열어보십시오. 뷰어는 압축되지 않은/인코딩되지 않은 파일이 유효한 XFDL 형식 인 경우 구문 분석하고 표시 할 수 있어야합니다.

0

gzip은 압축되지 않은 파일의 파일 이름에 따라 gzipped 파일의 길이가 달라 지도록 파일 헤더에 파일 이름을 넣습니다.

스트림에 GZIP 작용, 파일명은 생략하고, 다음의 일을해야하므로 파일이 약간 짧은 경우

GZIP은 yourform-unpacked.xml.gz

이어서

는에서 재 인코딩 64 기수 : base64로 -e의 yourform-unpacked.xml.gz yourform_reencoded.xfdl

어쩌면 이것은 같은 길이의 파일

1

확인이를 생성합니다 :

그들은 파이썬에

http://www.ourada.org/blog/archives/390

http://www.ourada.org/blog/archives/375

하지 루비,하지만 당신은 아주 가까이해야합니다.

그리고이 알고리즘은 실제로 'application/vnd.xfdl;이 아닌'application/x-xfdl; content-encoding = "asc-gzip"헤더가있는 파일입니다. content-encoding = "base64-gzip" ' 그러나 좋은 소식은 PureEdge (IBM Lotus Forms라고도 함)가 아무런 문제없이 해당 형식을 열 것이라는 점입니다. 그런 다음

여기에 (파이썬) base64로 GZIP 디코드이다, 그것을 위로합니다 그래서 당신은 전체 왕복 할 수 있습니다 :

with open(filename, 'r') as f: 
    header = f.readline() 
    if header == 'application/vnd.xfdl; content-encoding="base64-gzip"\n': 
    decoded = b'' 
    for line in f: 
     decoded += base64.b64decode(line.encode("ISO-8859-1")) 
    xml = zlib.decompress(decoded, zlib.MAX_WBITS + 16) 
+0

(내 블로그가 아닙니다.) 그리고 그 MAX_WBITS 마법에 대한 크레딧 : http://stackoverflow.com/questions/1838699/how-can-i-decompress-a-gzip-stream -와 - zlib – CrazyPyro

1

내가 Base64로 클래스의 도움에서 자바에서 이런 짓을 http://iharder.net/base64.

저는 Java에서 양식 조작을 수행하는 응용 프로그램에서 작업 해 왔습니다. 파일을 디코딩하고 XML에서 DOM 문서를 만든 다음 다시 파일에 씁니다. 파일을 읽을 수있는 자바

내 코드는 다음과 같습니다

/** 
    * Saves the current document to the specified location 
    * @param destination Desired destination for the file. 
    * @param asXML True if output needs should be as un-encoded XML not Base64/GZIP 
    * @throws IOException File cannot be created at specified location 
    * @throws TransformerConfigurationExample 
    * @throws TransformerException 
    */ 
    public void saveFile(String destination, boolean asXML) 
     throws IOException, 
      TransformerConfigurationException, 
      TransformerException 
     { 

     BufferedWriter bf = new BufferedWriter(new FileWriter(destination)); 
     bf.write(FILE_HEADER_BLOCK); 
     bf.newLine(); 
     bf.flush(); 
     bf.close(); 

     OutputStream outStream; 
     if(!asXML) { 
      outStream = new GZIPOutputStream(
       new Base64.OutputStream(
         new FileOutputStream(destination, true))); 
     } else { 
      outStream = new FileOutputStream(destination, true); 
     } 

     Transformer t = TransformerFactory.newInstance().newTransformer(); 
     t.transform(new DOMSource(doc), new StreamResult(outStream)); 

     outStream.flush(); 
     outStream.close();  
    } 

희망하는 데 도움이 :이 파일을 디스크에 기록과 같은 자바

public XFDLDocument(String inputFile) 
     throws IOException, 
      ParserConfigurationException, 
      SAXException 

{ 
    fileLocation = inputFile; 

    try{ 

     //create file object 
     File f = new File(inputFile); 
     if(!f.exists()) { 
      throw new IOException("Specified File could not be found!"); 
     } 

     //open file stream from file 
     FileInputStream fis = new FileInputStream(inputFile); 

     //Skip past the MIME header 
     fis.skip(FILE_HEADER_BLOCK.length()); 

     //Decompress from base 64     
     Base64.InputStream bis = new Base64.InputStream(fis, 
       Base64.DECODE); 

     //UnZIP the resulting stream 
     GZIPInputStream gis = new GZIPInputStream(bis); 

     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 
     doc = db.parse(gis); 

     gis.close(); 
     bis.close(); 
     fis.close(); 

    } 
    catch (ParserConfigurationException pce) { 
     throw new ParserConfigurationException("Error parsing XFDL from file."); 
    } 
    catch (SAXException saxe) { 
     throw new SAXException("Error parsing XFDL into XML Document."); 
    } 
} 

내 코드가 보인다.

1

나는 이런 식으로 일해 왔으며 이것은 PHP에서 작동 할 것입니다.쓰기 가능한 tmp 폴더가 있어야하고 PHP 파일의 이름은 example.php이어야합니다!

<?php 
    function gzdecode($data) { 
     $len = strlen($data); 
     if ($len < 18 || strcmp(substr($data,0,2),"\x1f\x8b")) { 
      echo "FILE NOT GZIP FORMAT"; 
      return null; // Not GZIP format (See RFC 1952) 
     } 
     $method = ord(substr($data,2,1)); // Compression method 
     $flags = ord(substr($data,3,1)); // Flags 
     if ($flags & 31 != $flags) { 
      // Reserved bits are set -- NOT ALLOWED by RFC 1952 
      echo "RESERVED BITS ARE SET. VERY BAD"; 
      return null; 
     } 
     // NOTE: $mtime may be negative (PHP integer limitations) 
     $mtime = unpack("V", substr($data,4,4)); 
     $mtime = $mtime[1]; 
     $xfl = substr($data,8,1); 
     $os = substr($data,8,1); 
     $headerlen = 10; 
     $extralen = 0; 
     $extra  = ""; 
     if ($flags & 4) { 
      // 2-byte length prefixed EXTRA data in header 
      if ($len - $headerlen - 2 < 8) { 
       return false; // Invalid format 
       echo "INVALID FORMAT"; 
      } 
      $extralen = unpack("v",substr($data,8,2)); 
      $extralen = $extralen[1]; 
      if ($len - $headerlen - 2 - $extralen < 8) { 
       return false; // Invalid format 
       echo "INVALID FORMAT"; 
      } 
      $extra = substr($data,10,$extralen); 
      $headerlen += 2 + $extralen; 
     } 

     $filenamelen = 0; 
     $filename = ""; 
     if ($flags & 8) { 
      // C-style string file NAME data in header 
      if ($len - $headerlen - 1 < 8) { 
       return false; // Invalid format 
       echo "INVALID FORMAT"; 
      } 
      $filenamelen = strpos(substr($data,8+$extralen),chr(0)); 
      if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) { 
       return false; // Invalid format 
       echo "INVALID FORMAT"; 
      } 
      $filename = substr($data,$headerlen,$filenamelen); 
      $headerlen += $filenamelen + 1; 
     } 

     $commentlen = 0; 
     $comment = ""; 
     if ($flags & 16) { 
      // C-style string COMMENT data in header 
      if ($len - $headerlen - 1 < 8) { 
       return false; // Invalid format 
       echo "INVALID FORMAT"; 
      } 
      $commentlen = strpos(substr($data,8+$extralen+$filenamelen),chr(0)); 
      if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) { 
       return false; // Invalid header format 
       echo "INVALID FORMAT"; 
      } 
      $comment = substr($data,$headerlen,$commentlen); 
      $headerlen += $commentlen + 1; 
     } 

     $headercrc = ""; 
     if ($flags & 1) { 
      // 2-bytes (lowest order) of CRC32 on header present 
      if ($len - $headerlen - 2 < 8) { 
       return false; // Invalid format 
       echo "INVALID FORMAT"; 
      } 
      $calccrc = crc32(substr($data,0,$headerlen)) & 0xffff; 
      $headercrc = unpack("v", substr($data,$headerlen,2)); 
      $headercrc = $headercrc[1]; 
      if ($headercrc != $calccrc) { 
       echo "BAD CRC"; 
       return false; // Bad header CRC 
      } 
      $headerlen += 2; 
     } 

     // GZIP FOOTER - These be negative due to PHP's limitations 
     $datacrc = unpack("V",substr($data,-8,4)); 
     $datacrc = $datacrc[1]; 
     $isize = unpack("V",substr($data,-4)); 
     $isize = $isize[1]; 

     // Perform the decompression: 
     $bodylen = $len-$headerlen-8; 
     if ($bodylen < 1) { 
      // This should never happen - IMPLEMENTATION BUG! 
      echo "BIG OOPS"; 
      return null; 
     } 
     $body = substr($data,$headerlen,$bodylen); 
     $data = ""; 
     if ($bodylen > 0) { 
      switch ($method) { 
       case 8: 
        // Currently the only supported compression method: 
        $data = gzinflate($body); 
        break; 
       default: 
        // Unknown compression method 
        echo "UNKNOWN COMPRESSION METHOD"; 
       return false; 
      } 
     } else { 
      // I'm not sure if zero-byte body content is allowed. 
      // Allow it for now... Do nothing... 
      echo "ITS EMPTY"; 
     } 

     // Verifiy decompressed size and CRC32: 
     // NOTE: This may fail with large data sizes depending on how 
     //  PHP's integer limitations affect strlen() since $isize 
     //  may be negative for large sizes. 
     if ($isize != strlen($data) || crc32($data) != $datacrc) { 
      // Bad format! Length or CRC doesn't match! 
      echo "LENGTH OR CRC DO NOT MATCH"; 
      return false; 
     } 
     return $data; 
    } 
    echo "<html><head></head><body>"; 
    if (empty($_REQUEST['upload'])) { 
     echo <<<_END 
    <form enctype="multipart/form-data" action="example.php" method="POST"> 
    <input type="hidden" name="MAX_FILE_SIZE" value="100000" /> 
    <table> 
    <th> 
    <input name="uploadedfile" type="file" /> 
    </th> 
    <tr> 
    <td><input type="submit" name="upload" value="Convert File" /></td> 
    </tr> 
    </table> 
    </form> 
    _END; 

    } 
    if (!empty($_REQUEST['upload'])) { 
     $file   = "tmp/" . $_FILES['uploadedfile']['name']; 
     $orgfile  = $_FILES['uploadedfile']['name']; 
     $name   = str_replace(".xfdl", "", $orgfile); 
     $convertedfile = "tmp/" . $name . ".xml"; 
     $compressedfile = "tmp/" . $name . ".gz"; 
     $finalfile  = "tmp/" . $name . "new.xfdl"; 
     $target_path = "tmp/"; 
     $target_path = $target_path . basename($_FILES['uploadedfile']['name']); 
     if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) { 
     } else { 
      echo "There was an error uploading the file, please try again!"; 
     } 
     $firstline  = "application/vnd.xfdl; content-encoding=\"base64-gzip\"\n"; 
     $data   = file($file); 
     $data   = array_slice($data, 1); 
     $raw   = implode($data); 
     $decoded  = base64_decode($raw); 
     $decompressed = gzdecode($decoded); 
     $compressed  = gzencode($decompressed); 
     $encoded  = base64_encode($compressed); 
     $decoded2  = base64_decode($encoded); 
     $decompressed2 = gzdecode($decoded2); 
     $header   = bin2hex(substr($decoded, 0, 10)); 
     $tail   = bin2hex(substr($decoded, -8)); 
     $header2  = bin2hex(substr($compressed, 0, 10)); 
     $tail2   = bin2hex(substr($compressed, -8)); 
     $header3  = bin2hex(substr($decoded2, 0, 10)); 
     $tail3   = bin2hex(substr($decoded2, -8)); 
     $filehandle  = fopen($compressedfile, 'w'); 
     fwrite($filehandle, $decoded); 
     fclose($filehandle); 
     $filehandle  = fopen($convertedfile, 'w'); 
     fwrite($filehandle, $decompressed); 
     fclose($filehandle); 
     $filehandle  = fopen($finalfile, 'w'); 
     fwrite($filehandle, $firstline); 
     fwrite($filehandle, $encoded); 
     fclose($filehandle); 
     echo "<center>"; 
     echo "<table style='text-align:center' >"; 
     echo "<tr><th>Stage 1</th>"; 
     echo "<th>Stage 2</th>"; 
     echo "<th>Stage 3</th></tr>"; 
     echo "<tr><td>RAW DATA -></td><td>DECODED DATA -></td><td>UNCOMPRESSED DATA -></td></tr>"; 
     echo "<tr><td>LENGTH: ".strlen($raw)."</td>"; 
     echo "<td>LENGTH: ".strlen($decoded)."</td>"; 
     echo "<td>LENGTH: ".strlen($decompressed)."</td></tr>"; 
     echo "<tr><td><a href='tmp/".$orgfile."'/>ORIGINAL</a></td><td>GZIP HEADER:".$header."</td><td><a href='".$convertedfile."'/>XML CONVERTED</a></td></tr>"; 
     echo "<tr><td></td><td>GZIP TAIL:".$tail."</td><td></td></tr>"; 
     echo "<tr><td><textarea cols='30' rows='20'>" . $raw . "</textarea></td>"; 
     echo "<td><textarea cols='30' rows='20'>" . $decoded . "</textarea></td>"; 
     echo "<td><textarea cols='30' rows='20'>" . $decompressed . "</textarea></td></tr>"; 
     echo "<tr><th>Stage 6</th>"; 
     echo "<th>Stage 5</th>"; 
     echo "<th>Stage 4</th></tr>"; 
     echo "<tr><td>ENCODED DATA <-</td><td>COMPRESSED DATA <-</td><td>UNCOMPRESSED DATA <-</td></tr>"; 
     echo "<tr><td>LENGTH: ".strlen($encoded)."</td>"; 
     echo "<td>LENGTH: ".strlen($compressed)."</td>"; 
     echo "<td>LENGTH: ".strlen($decompressed)."</td></tr>"; 
     echo "<tr><td></td><td>GZIP HEADER:".$header2."</td><td></td></tr>"; 
     echo "<tr><td></td><td>GZIP TAIL:".$tail2."</td><td></td></tr>"; 
     echo "<tr><td><a href='".$finalfile."'/>FINAL FILE</a></td><td><a href='".$compressedfile."'/>RE-COMPRESSED FILE</a></td><td></td></tr>"; 
     echo "<tr><td><textarea cols='30' rows='20'>" . $encoded . "</textarea></td>"; 
     echo "<td><textarea cols='30' rows='20'>" . $compressed . "</textarea></td>"; 
     echo "<td><textarea cols='30' rows='20'>" . $decompressed . "</textarea></td></tr>"; 
     echo "</table>"; 
     echo "</center>"; 
    } 
    echo "</body></html>"; 
    ?> 
관련 문제