Функция, чтобы определить, идентичен ли загруженный файл существующему

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: Есть ли такая функция, как get_checksum (из приведенного выше примера), доступная в стандартных библиотеках C/C++?

Q2: Если нет: что является лучшим способом для достижения этой цели?

Нет необходимости:
- очень продвинутая функция
- зашифрованные или защищенные контрольные суммы
- возможность сравнивать новый файл с файлами старше последнего, так как новый загруженный файл всегда будет перезаписывать более старый

  • 0
    Разве временные метки файла нельзя доверять?
  • 0
    @CareyGregory Не будут ли изменяться метки времени при загрузке нового файла?
Показать ещё 2 комментария
Теги:
file
checksum

3 ответа

0

Вы можете сделать хэш XOR, в котором вы просто xor последовательных блоков unsigned ints/longs, но это имеет проблемы с коллизиями. Например, если файл является главным образом символами, то большинство байтов будет в диапазоне обычных символов ASCII/Unicode, поэтому будет много неиспользуемого пространства ключей.

Для стандартной реализации вы можете прочитать файл в строке и использовать std :: hash из С++ 11. http://en.cppreference.com/w/cpp/utility/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;
}

Вам просто нужно прочитать файл в векторе.

  • 0
    Для чего стоит, если вы собираетесь написать этот хэш XOR, то вы можете легко обновить его до хеша DJB или подобного, это однострочное изменение. Это в основном приводит вас туда, где вы хотите, чтобы был std::hash<string> .
  • 0
    Некоторые реализации std :: hash для std :: string очень слабы - например, Microsoft обычно (и вполне может по-прежнему) выбирать 10 символов, равномерно распределенных вдоль строки, для включения - все остальные символы игнорируются. Может все еще быть достаточным, но это зависит от типов изменений, о которых известно, что файл подвергается.
0

На языке C++ ничего не было создано до тех пор, пока std :: hash <> в C++ 11 не будет очень простым, но может быть уместным для ваших нужд.

Последнее, что я проверил, ничего не существует в Boost (наиболее распространенное расширение библиотеки C++). Обоснование здесь обсуждается, но может быть датировано:

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

Итак, лучше всего:

std :: hash с содержимым файла.

Или что-то вроде следующего может быть полезно сохранить в простой заголовок и связать:

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

Или вы можете получить библиотеку, такую как OpenSSL или Crypto++.

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 */
};

Но вам нужно иметь разрешение на выполнение в файле, в котором вы его используете.

справочная страница

  • 0
    Но не изменится ли «время последнего доступа» и «время последней модификации» каждый раз, когда файл перезаписывается при новой загрузке?
  • 0
    Да, в этом случае вы можете использовать st_size для проверки размера файла, если он был изменен. Или любой другой параметр, который может удовлетворить ваши потребности.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню