Расчет MD5 для загрузки нескольких амазонок s3. android / java [дубликат]

Возможно, это должен быть комментарий к @ seanb123 и @Fredrick Gauss, комментирующий его комментарий, но для меня в Drupal 8.1 файл, который мне нужно было изменить, был здесь:

/etc/php/7.0/apache2/php.ini

четыре других файла php.ini, включая одну мою систему под названием «Загруженный файл конфигурации» (php -i | grep -i «загруженный файл конфигурации») и тот, который найден на странице info.php, но ни один из них не помог. Я нашел правильный путь на сайте с 2012 года, где он сказал, что путь был устаревшим даже НАЗАД. Конечно, для PHP7 это немного отличается от того, что он сказал тогда: /etc/php5/apache2/php.ini, но концепция была такой же.

Возможно, это поможет какой-то в противном случае беспомощному schmuck, как я.

. Говоря, ответ на OP в моем случае будет заключаться в том, что кто-то с привилегиями администратора на ящике должен будет это сделать.

Сайт, который мне помог: http://www.evilbox.ro/linux/remove-ispconfig-maximum-upload-size-of-2m-for-wordpress/

Это также рассматривается здесь: Ограничение размера файла импорта в PHPMyAdmin

34
задан broc.seib 29 August 2012 в 22:47
поделиться

10 ответов

Просто подтвержденный.

Предположим, вы загрузили 14-мегабайтный файл, а размер вашей части - 5 МБ. Вычислите 3 контрольные суммы MD5, соответствующие каждой части, то есть контрольную сумму первых 5 МБ, вторую 5 МБ и последние 4 МБ. Затем возьмите контрольную сумму их конкатенации. Поскольку контрольные суммы MD5 представляют собой шестнадцатеричные представления двоичных данных, просто убедитесь, что вы принимаете MD5 декодированной двоичной конкатенации, а не кодированной конкатенации ASCII или UTF-8. Когда это будет сделано, добавьте дефис и количество деталей, чтобы получить ETag.

Вот команды, которые нужно сделать на Mac OS X с консоли:

$ dd bs=1m count=5 skip=0 if=someFile | md5 >>checksums.txt
5+0 records in
5+0 records out
5242880 bytes transferred in 0.019611 secs (267345449 bytes/sec)
$ dd bs=1m count=5 skip=5 if=someFile | md5 >>checksums.txt
5+0 records in
5+0 records out
5242880 bytes transferred in 0.019182 secs (273323380 bytes/sec)
$ dd bs=1m count=5 skip=10 if=someFile | md5 >>checksums.txt
2+1 records in
2+1 records out
2599812 bytes transferred in 0.011112 secs (233964895 bytes/sec)

В этот момент все контрольные суммы находятся в checksums.txt. Чтобы связать их и декодировать гекс и получить контрольную сумму MD5 для партии, просто используйте

$ xxd -r -p checksums.txt | md5

. Теперь добавьте «-3», чтобы получить ETag, так как было 3 части.

Стоит отметить, что md5 в Mac OS X просто выписывает контрольную сумму, но md5sum в Linux также выводит имя файла. Вам нужно снять это, но я уверен, что есть возможность только выводить контрольные суммы.

Примечание. Если вы загрузили aws-cli через aws s3 cp, то у вас, скорее всего, есть 8MB chunksize. Согласно документам , это по умолчанию.

Обновление: мне рассказали о реализации этого в https://github.com/Teachnova/s3md5 , который не работает на OS X. Вот Gist, который я написал с рабочим скриптом для OS X .

55
ответ дан Bruno Bronosky 27 August 2018 в 07:47
поделиться

В приведенном выше ответе кто-то спросил, есть ли способ получить файл md5 для файлов размером более 5G.

Ответ, который я мог бы дать для получения значения MD5 (для файлов размером более 5G), состоял бы в том, чтобы либо добавить его вручную в метаданные, либо использовать программу для загрузки, которая добавит эту информацию.

Например, я использовал s3cmd для загрузки файла и добавил следующие метаданные.

$ aws s3api head-object --bucket xxxxxxx --key noarch/epel-release-6-8.noarch.rpm 
{
  "AcceptRanges": "bytes", 
  "ContentType": "binary/octet-stream", 
  "LastModified": "Sat, 19 Sep 2015 03:27:25 GMT", 
  "ContentLength": 14540, 
  "ETag": "\"2cd0ae668a585a14e07c2ea4f264d79b\"", 
  "Metadata": {
    "s3cmd-attrs": "uid:502/gname:staff/uname:xxxxxx/gid:20/mode:33188/mtime:1352129496/atime:1441758431/md5:2cd0ae668a585a14e07c2ea4f264d79b/ctime:1441385182"
  }
}

Это не прямое решение с использованием ETag, но это способ заполнить нужные метаданные (MD5) таким образом, чтобы вы могли получить к нему доступ. Он все равно будет терпеть неудачу, если кто-то загрузит файл без метаданных.

4
ответ дан Cinderhaze 27 August 2018 в 07:47
поделиться

Тот же алгоритм, java-версия: (BaseEncoding, Hasher, Hashing и т. д. поступает из библиотеки guava

/**
 * Generate checksum for object came from multipart upload</p>
 * </p>
 * AWS S3 spec: Entity tag that identifies the newly created object's data. Objects with different object data will have different entity tags. The entity tag is an opaque string. The entity tag may or may not be an MD5 digest of the object data. If the entity tag is not an MD5 digest of the object data, it will contain one or more nonhexadecimal characters and/or will consist of less than 32 or more than 32 hexadecimal digits.</p> 
 * Algorithm follows AWS S3 implementation: https://github.com/Teachnova/s3md5</p>
 */
private static String calculateChecksumForMultipartUpload(List<String> md5s) {      
    StringBuilder stringBuilder = new StringBuilder();
    for (String md5:md5s) {
        stringBuilder.append(md5);
    }

    String hex = stringBuilder.toString();
    byte raw[] = BaseEncoding.base16().decode(hex.toUpperCase());
    Hasher hasher = Hashing.md5().newHasher();
    hasher.putBytes(raw);
    String digest = hasher.hash().toString();

    return digest + "-" + md5s.size();
}
8
ответ дан djb 27 August 2018 в 07:47
поделиться

На основе ответов здесь я написал реализацию Python, которая корректно вычисляет как многочастные, так и одночастные файлы ETags.

def calculate_s3_etag(file_path, chunk_size=8 * 1024 * 1024):
    md5s = []

    with open(file_path, 'rb') as fp:
        while True:
            data = fp.read(chunk_size)
            if not data:
                break
            md5s.append(hashlib.md5(data))

    if len(md5s) == 1:
        return '"{}"'.format(md5s[0].hexdigest())

    digests = b''.join(m.digest() for m in md5s)
    digests_md5 = hashlib.md5(digests)
    return '"{}-{}"'.format(digests_md5.hexdigest(), len(md5s))

По умолчанию chunk_size имеет 8 МБ, используемый официальным aws cli инструмент, и он делает многостраничную загрузку для 2+ кусков. Он должен работать как на Python 2, так и на 3.

4
ответ дан hyperknot 27 August 2018 в 07:47
поделиться

Не уверен, что это может помочь:

В настоящее время мы делаем уродливое (но до сих пор полезное) взлома fix тех неправильных ETags в многофайловых загруженных файлах, которые состоят в применении изменения к файлу в ведре; который запускает пересчет md5 из Amazon, который изменяет ETag на совпадения с фактической сигнатурой md5.

В нашем случае:

Файл: bucket / Foo.mpg.gpg

  1. ETag получен: «3f92dffef0a11d175e60fb8b958b4e6e-2»
  2. Сделайте что-то с файлом ( переименуйте его , добавьте метаданные, такие как поддельный заголовок, среди прочих)
  3. Полученный Etag: «c1d903ca1bb6dc68778ef21e74cc15b0»

Мы не знаем алгоритм, но поскольку мы можем «исправить» ETag, мы надеемся Не нужно беспокоиться об этом.

7
ответ дан juanjocv 27 August 2018 в 07:47
поделиться

Нет,

До сих пор нет решения для соответствия нормальному файлу ETag и Multipart файлов ETag и MD5 локального файла.

-1
ответ дан Tej Kiran 27 August 2018 в 07:47
поделиться

И вот PHP-версия вычисления ETag:

function calculate_aws_etag($filename, $chunksize) {
    /*
    DESCRIPTION:
    - calculate Amazon AWS ETag used on the S3 service
    INPUT:
    - $filename : path to file to check
    - $chunksize : chunk size in Megabytes
    OUTPUT:
    - ETag (string)
    */
    $chunkbytes = $chunksize*1024*1024;
    if (filesize($filename) < $chunkbytes) {
        return md5_file($filename);
    } else {
        $md5s = array();
        $handle = fopen($filename, 'rb');
        if ($handle === false) {
            return false;
        }
        while (!feof($handle)) {
            $buffer = fread($handle, $chunkbytes);
            $md5s[] = md5($buffer);
            unset($buffer);
        }
        fclose($handle);

        $concat = '';
        foreach ($md5s as $indx => $md5) {
            $concat .= hex2bin($md5);
        }
        return md5($concat) .'-'. count($md5s);
    }
}

$etag = calculate_aws_etag('path/to/myfile.ext', 8);

И вот расширенная версия, которая может проверять ожидаемый ETag - и даже догадываться о chunksize, если вы этого не знаете !

function calculate_etag($filename, $chunksize, $expected = false) {
    /*
    DESCRIPTION:
    - calculate Amazon AWS ETag used on the S3 service
    INPUT:
    - $filename : path to file to check
    - $chunksize : chunk size in Megabytes
    - $expected : verify calculated etag against this specified etag and return true or false instead
        - if you make chunksize negative (eg. -8 instead of 8) the function will guess the chunksize by checking all possible sizes given the number of parts mentioned in $expected
    OUTPUT:
    - ETag (string)
    - or boolean true|false if $expected is set
    */
    if ($chunksize < 0) {
        $do_guess = true;
        $chunksize = 0 - $chunksize;
    } else {
        $do_guess = false;
    }

    $chunkbytes = $chunksize*1024*1024;
    $filesize = filesize($filename);
    if ($filesize < $chunkbytes && (!$expected || !preg_match("/^\\w{32}-\\w+$/", $expected))) {
        $return = md5_file($filename);
        if ($expected) {
            $expected = strtolower($expected);
            return ($expected === $return ? true : false);
        } else {
            return $return;
        }
    } else {
        $md5s = array();
        $handle = fopen($filename, 'rb');
        if ($handle === false) {
            return false;
        }
        while (!feof($handle)) {
            $buffer = fread($handle, $chunkbytes);
            $md5s[] = md5($buffer);
            unset($buffer);
        }
        fclose($handle);

        $concat = '';
        foreach ($md5s as $indx => $md5) {
            $concat .= hex2bin($md5);
        }
        $return = md5($concat) .'-'. count($md5s);
        if ($expected) {
            $expected = strtolower($expected);
            $matches = ($expected === $return ? true : false);
            if ($matches || $do_guess == false || strlen($expected) == 32) {
                return $matches;
            } else {
                // Guess the chunk size
                preg_match("/-(\\d+)$/", $expected, $match);
                $parts = $match[1];
                $min_chunk = ceil($filesize / $parts /1024/1024);
                $max_chunk =  floor($filesize / ($parts-1) /1024/1024);
                $found_match = false;
                for ($i = $min_chunk; $i <= $max_chunk; $i++) {
                    if (calculate_aws_etag($filename, $i) === $expected) {
                        $found_match = true;
                        break;
                    }
                }
                return $found_match;
            }
        } else {
            return $return;
        }
    }
}
1
ответ дан TheStoryCoder 27 August 2018 в 07:47
поделиться

Согласно документации AWS, ETag не является хешем MD5 для многострановой загрузки или для зашифрованного объекта: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonResponseHeaders .html

Объекты, созданные объектом PUT Object, POST Object или Copy, или через консоль управления AWS, и зашифрованы SSE-S3 или открытым текстом, имеют ETags, которые представляют собой дайджест MD5 их объектных данных.

Объекты, созданные объектом PUT, POST Object или Copy, или через AWS Management Console и зашифрованные SSE-C или SSE-KMS, имеют ETags, которые не являются дайджестом MD5 их данных объекта.

Если объект создается с помощью операции Multipart Upload или Part Copy, ETag не является дайджестом MD5, независимо от метода шифрования.

3
ответ дан Timothy Gonzalez 27 August 2018 в 07:47
поделиться

bash implementation

реализация python

Алгоритм буквально (скопирован из readme в реализации python):

  1. md5 куски
  2. glob строки md5 вместе
  3. преобразуют glob в двоичный
  4. md5 двоичный код globbed chunk md5s
  5. добавить "-Number_of_chunks" в конец строки md5 двоичного файла
5
ответ дан tlastowka 27 August 2018 в 07:47
поделиться

Вот алгоритм в ruby ​​...

require 'digest'

# PART_SIZE should match the chosen part size of the multipart upload
# Set here as 10MB
PART_SIZE = 1024*1024*10 

class File
  def each_part(part_size = PART_SIZE)
    yield read(part_size) until eof?
  end
end

file = File.new('<path_to_file>')

hashes = []

file.each_part do |part|
  hashes << Digest::MD5.hexdigest(part)
end

multipart_hash = Digest::MD5.hexdigest([hashes.join].pack('H*'))
multipart_etag = "#{multipart_hash}-#{hashes.count}"

Благодаря Shortest Hex2Bin в Ruby и Multipart Загружает на S3 ...

1
ответ дан vince 27 August 2018 в 07:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: