2014-04-15 2 views
0

다른 컴퓨터 또는 인터넷에서 다운로드 한 파일을 구문 분석하고 해당 파일에서 정보를 수집해야하는 Linux 프로그램을 개발 중입니다. 프로그램은 또한 루틴, 매 n 일/시간/분/시간마다 파일을 다시 다운로드해야하며 파일이 변경된 경우 계속 업데이트하기 위해 다시 구문 분석해야합니다.다운로드 한 파일이 기존 파일과 동일한 지 여부를 확인하는 기능

그러나 파일을 구문 분석하는 프로세스에는 많은 리소스가 필요할 수 있습니다. 따라서 파일을 마지막으로 다운로드 한 후 파일이 변경되었는지 확인하는 기능이 필요합니다.

int get_checksum(char *filename) { 
    // New prototype, if no such function already exists in standard C-libraries 
    int result;   // Or char/float/whatever 


    // ... 


    return result; 
} 
int main(void) { 

    char filename[] = { "foo.dat" }; 
    char file_url[] = { "http://example.com/foo.dat" } 
    int old_checksum;  // Or char/float/whatever 
    int new_checksum;  // Or char/float/whatever 


    // ... 


    // Now assume that old_checksum has a value from before: 

    dl_file(filename, file_url); // Some prototype for downloading the file 
    if ((new_checksum = get_checksum(filename)) == -1) { 
     // Badness 
    } 
    else { 
     if (new_checksum != old_checksum) { 
      old_checksum = new_checksum; 
      // Parse the file 
     } 
     else { 
      // Do nothing 
     } 
    } 


    // ... 


} 

Q1 :/C++ 라이브러리 표준 C에서 사용할 수get_checksum(위의 예에서)와 같은 기능이 있나요 나는이 예제 같은 것을 상상?

질문 2 :이 목적을 달성하는 가장 좋은 방법은 무엇입니까? 매우 고급 기능
- - 암호화 또는 보안 체크섬
- 마지막보다 오래된 파일에 새 파일을 비교 할 수있는 능력, 새로운 다운로드 한 파일부터 항상 것입니다
: 거기가 필요하지 않다고

이전 버전을 덮어 씁니다.

+0

파일 타임 스탬프를 신뢰할 수 없습니까? –

+0

@CareyGregory 새 파일을 다운로드 할 때 타임 스탬프가 변경되지 않습니까? – SeagulFish

+0

다운로드하기 전에 원본 컴퓨터에서 타임 스탬프를 얻을 수 있다고 생각했습니다. 그렇게 할 수 있다면 다운로드를 건너 뛸 수 있습니다. –

답변

0

stat() 기능을 사용할 수 있습니다. 그것은 파일 크기 등, 마지막 액세스 시간과 같은 파일 매개 변수, 마지막 수정의 시간에 액세스 할 수 있습니다

struct stat { 
    dev_t  st_dev;  /* ID of device containing file */ 
    ino_t  st_ino;  /* inode number */ 
    mode_t st_mode; /* protection */ 
    nlink_t st_nlink; /* number of hard links */ 
    uid_t  st_uid;  /* user ID of owner */ 
    gid_t  st_gid;  /* group ID of owner */ 
    dev_t  st_rdev; /* device ID (if special file) */ 
    off_t  st_size; /* total size, in bytes */ 
    blksize_t st_blksize; /* blocksize for file system I/O */ 
    blkcnt_t st_blocks; /* number of 512B blocks allocated */ 
    time_t st_atime; /* time of last access */ 
    time_t st_mtime; /* time of last modification */ 
    time_t st_ctime; /* time of last status change */ 
}; 

그러나 당신은 당신이 그것을 사용하는 것 파일에 실행 권한이 있어야합니다.

man page

+0

그러나 새 다운로드로 파일을 덮어 쓸 때마다 "마지막 액세스 시간"및 "마지막 수정 시간"이 변경되지 않습니까? – SeagulFish

+0

그렇다면, 수정 된 경우 파일 크기를 확인하기 위해'st_size'를 사용할 수 있습니다. 또는 귀하의 필요에 맞는 다른 매개 변수. – brokenfoot

0

당신은 XOR 해시를 할 수있는 당신이 바로 XOR 연속 부호의 int/long 치의 블록,하지만이 충돌 문제가있다. 예를 들어 파일이 대부분 문자 인 경우 대부분의 바이트는 일반 ASCII/유니 코드 문자의 범위에 있으므로 사용되지 않는 키 공간이 많이 있습니다.

표준 구현의 경우 파일을 문자열로 읽고 C++ 11의 std :: hash를 사용할 수 있습니다. 당신은 단지 벡터로 파일을 읽을 필요

unsigned int hash(vector<char> file){ 
    unsigned int result; 
    int *arr = (int*)file.data(); 

    for(int i = 0;i < file.size()/sizeof(unsigned int);i++) 
     result ^= arr[i]; 

    return result; 
} 

다음 http://en.cppreference.com/w/cpp/utility/hash

첫 번째 방법의 예입니다.

+0

가치가 있다면, XOR 해시를 작성하면 DJB 해시 또는 유사한 것으로 쉽게 업그레이드 할 수 있습니다. 단 한 줄만 변경하면됩니다. 기본적으로'std :: hash '을 원하는 곳으로 가져옵니다. –

+0

std :: string에 대한 std :: hash의 일부 구현은 매우 약합니다. 마이크로 소프트는 문자열을 따라 균등하게 간격을 둔 10 개의 문자를 선택하는 데 익숙합니다. (다른 문자는 무시됩니다.) 여전히 충분할 수도 있지만 파일이받는 수정 유형에 따라 다릅니다. –

0

C++ 언어에서는 std :: hash <> C++ 11까지는 아무것도 작성되지 않았지만 매우 간단하지만 사용자의 필요에 따라 적절할 수 있습니다.

마지막으로 Boost (가장 일반적인 C++ 라이브러리 확장)에 아무것도 없다고 확인했습니다. 추론은 여기에 대해 이야기하지만, 일 수있다 : 파일 내용

std::hash :

http://www.gamedev.net/topic/528553-why-doesnt-boost-have-a-cryptographic-hash-library/

그래서, 당신은 최선의 방법이있어.

http://www.zedwood.com/article/cpp-md5-function

또는 당신은 OpenSSL 또는 Crypto++ 등의 라이브러리를 얻을 수 :

또는 다음과 같은

간단한 헤더에 저장 및 연결 사용이 될 수 있습니다.

관련 문제