7Z 아카이브 형식에 이진 데이터를 어떻게 작성합니까?
문제
7Z 아카이브 형식의 형식 설명 및 소스 코드를 쏟아 부었지만 여전히 유효한 컨테이너를 작성하는 데 여전히 어려움이 있습니다. 빈 컨테이너를 만들 수 있다고 생각합니다 ... 어쨌든 여기 내 시작이 있습니다.
std::ofstream ofs(archivename.c_str(), std::ios::binary|std::ios::trunc);
Byte signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
Byte major = 0;
Byte minor = 3;
ofs.write((const char*)signature, 6);
ofs.write((const char*)major, 1);
ofs.write((const char*)minor, 1);
UInt64 offset = 0;
UInt64 size = 0;
UInt32 crc = 0;
ofs.write((const char*)offset, 4);
ofs.write((const char*)size, 8);
ofs.write((const char*)crc, 8);
ofs.write((const char*)CrcCalc(0, 0), 8);
ofs.close();
내 주요 문제는 std :: ofstream :: write ()에 대한 이해가 부족하다고 생각합니다. 바이트는 '부호없는 숯'이며 UINT64 & UINT32는 모두 '부호없는 길다'입니다.
업데이트 0: 모두가 지적했듯이, 빅 엔디안 기계에서 이것을 실행하면 문제가 될 것입니다. 여기에는 그렇지 않습니다. 프레드릭 얀센 (Fredrik Janssen)에 따르면, 나는 비 배열의 주소를 던져야한다. 또한 crccalc ()가 LZMA SDK의 함수라고 언급해야합니다. 추가 및 도움이되는 것은 약간의 문제가있는 첫 번째 부호없는 Char [6]입니다.
업데이트 1: 아래에서 빈 아카이브 파일을 가져 오려는 작업 코드.
static void SetUInt32(Byte *p, UInt32 d)
{
for (int i = 0; i < 4; i++, d >>= 8)
p[i] = (Byte)d;
}
static void SetUInt64(Byte *p, UInt64 d)
{
for (int i = 0; i < 8; i++, d >>= 8)
p[i] = (Byte)d;
}
void make_7z_archive()
{
CrcGenerateTable();
std::ofstream ofs(archivename.c_str(), std::ios::binary|std::ios::trunc);
Byte signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
Byte major = 0;
Byte minor = 3;
ofs.write((const char*)signature, 6);
ofs.write((const char*)&major, 1);
ofs.write((const char*)&minor, 1);
UInt64 offset = 0;
UInt64 size = 0;
UInt32 crc = 0;
Byte buf[24];
SetUInt64(buf + 4, offset);
SetUInt64(buf + 12, size);
SetUInt32(buf + 20, crc);
SetUInt32(buf, CrcCalc(buf + 4, 20));
ofs.write((const char*)buf, 24);
ofs.close();
}
참고 : crcgeneratetable () 및 crccalc ()는 LZMA SDK에서 나온 것입니다.
해결책
7Z 형식을 알지 못하지만 오프셋, 크기 및 CRC를 기록 할 때이 파일에 Little-Endian 형식의 파일에 기록 될 것임을 알 수 있습니다 (Little-Endian CPU가 있다고 가정합니다).
편집 : 아마도 더 나빠서, 당신은 아마도 메이저, 마이너, 오프셋, 크기 및 CRC 이전에 누락되어 실제 값을 포인터로 캐스팅하고 있습니다.
다른 팁
어 ... 혼란 스러워요. 그것은 있습니다 SDK... 당신이 당신의 게시물에서 언급 한 ... 또한 7-zip 소스는 온라인입니다. 또한보십시오 P7ZIP Sourceforge에서. 방금 P7ZIP 소스를 보았고 트릭을 수행하는 것처럼 보이는 "7Z"로 시작하는 파일이 많이 있습니다.
나는 7Z 형식을 프로그램 적으로 사용하지 않았지만 (명령 줄 UTIL / GUI를 통해서만) 왜 SDK보다는 저수준을 직접 처리해야합니까? (LGPL 라이센스 때문에)