Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon s3 如何在Amazon';s S3_Amazon S3 - Fatal编程技术网

Amazon s3 如何在Amazon';s S3

Amazon s3 如何在Amazon';s S3,amazon-s3,Amazon S3,如果我在Amazon的S3上有现有文件,那么不必下载文件就可以获得md5sum的最简单方法是什么 谢谢对于多部分上传,ETag似乎不是MD5(根据Gael Fraiteur的评论)。在这些情况下,它包含一个减号后缀和一个数字。然而,即使减号之前的位似乎也不是MD5,尽管它的长度与MD5相同。后缀可能是上传的部件数量?我已经对照上传文件的MD5sum交叉检查了jets3t和管理控制台,ETag似乎等于MD5sum。您可以在AWS管理控制台中查看文件的属性: 这对我很有用。 在PHP中,您可以使用以

如果我在Amazon的S3上有现有文件,那么不必下载文件就可以获得md5sum的最简单方法是什么


谢谢

对于多部分上传,ETag似乎不是MD5(根据Gael Fraiteur的评论)。在这些情况下,它包含一个减号后缀和一个数字。然而,即使减号之前的位似乎也不是MD5,尽管它的长度与MD5相同。后缀可能是上传的部件数量?

我已经对照上传文件的MD5sum交叉检查了jets3t和管理控制台,ETag似乎等于MD5sum。您可以在AWS管理控制台中查看文件的属性:

这对我很有用。 在PHP中,您可以使用以下方法比较本地文件和amazon文件之间的校验和:



    // get localfile md5
    $checksum_local_file = md5_file ( '/home/file' );

    // compare checksum between localfile and s3file    
    public function compareChecksumFile($file_s3, $checksum_local_file) {

        $Connection = new AmazonS3 ();
        $bucket = amazon_bucket;
        $header = $Connection->get_object_headers( $bucket, $file_s3 );

        // get header
        if (empty ( $header ) || ! is_object ( $header )) {
            throw new RuntimeException('checksum error');
        }
        $head = $header->header;
        if (empty ( $head ) || !is_array($head)) {
            throw new RuntimeException('checksum error');
        }
        // get etag (md5 amazon)
        $etag = $head['etag'];
        if (empty ( $etag )) {
            throw new RuntimeException('checksum error');
        }
        // remove quotes
        $checksumS3 = str_replace('"', '', $etag);

        // compare md5
        if ($checksum_local_file === $checksumS3) {
            return TRUE;
        } else {
            return FALSE;
        }
    }


对于那些花时间四处搜索以找出md5为何与S3中的ETag不同的人来说

ETag将根据chuck of data和concat all md5hash进行计算,以再次生成md5 hash,并将区块数保留在最后

下面是生成哈希的C#版本

    string etag = HashOf("file.txt",8);
源代码

    private string HashOf(string filename,int chunkSizeInMb)
    {
        string returnMD5 = string.Empty;
        int chunkSize = chunkSizeInMb * 1024 * 1024;

        using (var crypto = new MD5CryptoServiceProvider())
        {
            int hashLength = crypto.HashSize/8;

            using (var stream = File.OpenRead(filename))
            {
                if (stream.Length > chunkSize)
                {
                    int chunkCount = (int)Math.Ceiling((double)stream.Length/(double)chunkSize);

                    byte[] hash = new byte[chunkCount*hashLength];
                    Stream hashStream = new MemoryStream(hash);

                    long nByteLeftToRead = stream.Length;
                    while (nByteLeftToRead > 0)
                    {
                        int nByteCurrentRead = (int)Math.Min(nByteLeftToRead, chunkSize);
                        byte[] buffer = new byte[nByteCurrentRead];
                        nByteLeftToRead -= stream.Read(buffer, 0, nByteCurrentRead);

                        byte[] tmpHash = crypto.ComputeHash(buffer);

                        hashStream.Write(tmpHash, 0, hashLength);

                    }

                    returnMD5 = BitConverter.ToString(crypto.ComputeHash(hash)).Replace("-", string.Empty).ToLower()+"-"+ chunkCount;
                }
                else {
                    returnMD5 = BitConverter.ToString(crypto.ComputeHash(stream)).Replace("-", string.Empty).ToLower();

                }
                stream.Close();
            }
        }
        return returnMD5;
    }

AWS关于ETag的文件规定:

实体标记是对象的散列。ETag只反映对象内容的更改,而不反映其元数据。ETag可能是也可能不是对象数据的MD5摘要。是否是取决于对象是如何创建的,以及它是如何按照如下所述进行加密的:

  • 由PUT对象、POST对象或复制操作创建的对象,或通过AWS管理控制台创建的对象,并由SSE-S3或明文加密,其ETag是其对象数据的MD5摘要
  • 由PUT对象、POST对象或复制操作创建的对象,或通过AWS管理控制台创建的对象,并由SSE-C或SSE-KMS加密,其ETag不是其对象数据的MD5摘要
  • 如果通过多部分上载或部分复制操作创建对象,则无论采用何种加密方法,ETag都不是MD5摘要

参考资料:

以下是根据2017获取MD5哈希的代码

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Base64;
public class GenerateMD5 {
public static void main(String args[]) throws Exception{
    String s = "<CORSConfiguration> <CORSRule> <AllowedOrigin>http://www.example.com</AllowedOrigin> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <AllowedHeader>*</AllowedHeader> <MaxAgeSeconds>3000</MaxAgeSeconds> </CORSRule> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedHeader>*</AllowedHeader> <MaxAgeSeconds>3000</MaxAgeSeconds> </CORSRule> </CORSConfiguration>";

        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(s.getBytes());
        byte[] digest = md.digest();
        StringBuffer sb = new StringBuffer();
        /*for (byte b : digest) {
            sb.append(String.format("%02x", b & 0xff));
        }*/
        System.out.println(sb.toString());
        StringBuffer sbi = new StringBuffer();
        byte [] bytes = Base64.encodeBase64(digest);
        String finalString = new String(bytes);
        System.out.println(finalString);
    }
}
import java.security.MessageDigest;
导入java.security.NoSuchAlgorithmException;
导入org.apache.commons.codec.binary.Base64;
公共类生成器D5{
公共静态void main(字符串args[])引发异常{
字符串s=”http://www.example.com 将帖子删除*3000*获取*3000”;
MessageDigest md=MessageDigest.getInstance(“MD5”);
md.update(s.getBytes());
字节[]摘要=md.digest();
StringBuffer sb=新的StringBuffer();
/*for(字节b:摘要){
sb.append(字符串格式(“%02x”,b&0xff));
}*/
System.out.println(sb.toString());
StringBuffer sbi=新的StringBuffer();
byte[]bytes=Base64.encodeBase64(摘要);
字符串finalString=新字符串(字节);
系统输出打印LN(最终打印);
}
}

注释代码是大多数人错误的地方,将其更改为十六进制

以下是获取PowerShell中从c#转换的对象的S3 ETag的代码

我发现s3cmd有一个--list-md5选项,可以与ls命令一起使用,例如

s3cmd ls --list-md5 s3://bucket_of_mine/

希望这有帮助。

最简单的方法是在将这些文件上载到bucket之前,将校验和设置为元数据:

ObjectMetadata md=newObjectMetadata();
md.setContentMD5(“foobar”);
PutObjectRequest req=新的PutObjectRequest(BUCKET、KEY、新文件(“/path/to/File”))。带有元数据(md);
tm.upload(req.waitForUploadResult();
现在,您无需下载文件即可访问这些元数据:

ObjectMetadata md2=s3Client.getObjectMetadata(BUCKET,KEY);
System.out.println(md.getContentMD5());

来源:

下面是我比较本地文件校验和与s3 etag的工作。 我用的是Python

def md5_校验和(文件名): m=hashlib.md5() 将open(filename,'rb')作为f: 对于iter中的数据(λ:f.read(1024*1024),b''): m、 更新(数据) 返回m.hexdigest() def etag_校验和(文件名,块大小=8*1024*1024): md5s=[] 将open(filename,'rb')作为f: 对于iter中的数据(lambda:f.read(块大小),b''): append(hashlib.md5(data.digest()) m=hashlib.md5(b.)。加入(md5s)) 打印(“{}-{}.”格式(m.hexdigest(),len(md5s))) 返回'{}-{}'。格式(m.hexdigest(),len(md5s)) def etag_比较(文件名,etag): et=etag[1:-1]#带引号 打印('et',et) 如果et中的“-”和et==etag_校验和(文件名): 返回真值 如果“-”不在et中且et==md5_校验和(文件名): 返回真值 返回错误 def main(): session=bot3.session( aws\u访问密钥\u id=s3\u访问密钥, aws_secret_access_key=s3_secret ) s3=会话。客户端('s3') obj_dict=s3.get_对象(Bucket=Bucket\u name,Key=your\u Key) etag=(obj_dict['etag']) 打印('etag',etag) 验证=etag\u比较(文件名,etag) 打印(验证) etag_校验和(文件名,块大小=8*1024*1024)
返回验证这是一个非常老的问题,但我很难找到下面的信息,这是我能找到的第一个地方,所以我想详细说明一下,以防有人需要

ETag是MD5。但是对于多部分上传的文件,MD5是从每个上传部分的MD5的串联计算出来的。 因此,您不需要在服务器中计算MD5。只要拿到ETag就行了

正如@EmersonFarrugia在回答时所说:

假设你上传了一个14MB的文件,你的部件大小是5MB。计算每个部分对应的3个MD5校验和,即前5MB、第二5MB和最后4MB的校验和。然后取它们连接的校验和。由于MD5校验和是二进制数据的十六进制表示形式,因此只需确保采用解码二进制级联的MD5,而不是ASCII或UTF-8编码级联的MD5
s3cmd ls --list-md5 s3://bucket_of_mine/
#!/bin/bash
set -euo pipefail
if [ $# -ne 2 ]; then
    echo "Usage: $0 file partSizeInMb";
    exit 0;
fi
file=$1
if [ ! -f "$file" ]; then
    echo "Error: $file not found." 
    exit 1;
fi
partSizeInMb=$2
fileSizeInMb=$(du -m "$file" | cut -f 1)
parts=$((fileSizeInMb / partSizeInMb))
if [[ $((fileSizeInMb % partSizeInMb)) -gt 0 ]]; then
    parts=$((parts + 1));
fi
checksumFile=$(mktemp -t s3md5.XXXXXXXXXXXXX)
for (( part=0; part<$parts; part++ ))
do
    skip=$((partSizeInMb * part))
    $(dd bs=1M count=$partSizeInMb skip=$skip if="$file" 2> /dev/null | md5sum >> $checksumFile)
done
etag=$(echo $(xxd -r -p $checksumFile | md5sum)-$parts | sed 's/ --/-/')
echo -e "${1}\t${etag}"
rm $checksumFile
#!/bin/bash

if [ $# -ne 2 ]; then
    echo "Usage: $0 file partSizeInMb";
    exit 0;
fi

file=$1

if [ ! -f "$file" ]; then
    echo "Error: $file not found." 
    exit 1;
fi

partSizeInMb=$2
fileSizeInMb=$(du -m "$file" | cut -f 1)
parts=$((fileSizeInMb / partSizeInMb))
if [[ $((fileSizeInMb % partSizeInMb)) -gt 0 ]]; then
    parts=$((parts + 1));
fi

checksumFile=$(mktemp -t s3md5)

for (( part=0; part<$parts; part++ ))
do
    skip=$((partSizeInMb * part))
    $(dd bs=1m count=$partSizeInMb skip=$skip if="$file" 2>/dev/null | md5 >>$checksumFile)
done

echo $(xxd -r -p $checksumFile | md5)-$parts
rm $checksumFile