回答
嗯......我想你可以看看ETag头。 (在这种情况下,您可以使用HTTP HEAD方法而不是GET)。他们不太明确地说,但几乎可以肯定,Amazon使用MD5散列作为ETag。从PUT Object documentation(说不上来为什么他们不只是直截了当地说):
为了确保数据不被损坏,在网络上,使用Content-MD5标头。当您使用Content-MD5标头时,Amazon S3会根据提供的MD5值检查对象。如果它们不匹配,则Amazon S3会返回错误。此外,您可以在将对象放入Amazon S3时计算MD5,并将返回的Etag与计算出的MD5值进行比较。
此外,SOAP methods让您只请求元数据而不是数据本身。
这个回答不再有效。 Etag也可以返回一些不同的东西,例如“08e1ef8708f6b9ba5f65596254f45111-1” – 2011-09-01 15:03:01
如果我使用s3cmd上传,它会显式设置ETag为上传文件的(正确)MD5校验和。希望s3cmd也可以验证通过'put'上传的文件的校验和(http://aws.amazon.com/articles/1904)。 – 2012-06-07 20:01:47
@AdamMonsen我不认为s3cmd会将ETag设置为MD5,因为在Web界面中,多部分上传文件的ETag仍然显示上面提到的内容中带有短划线的格式。算法如何计算ETag在[这个答案](http://stackoverflow.com/a/19304527/1132850)中解释。我想s3cmd设置一个自定义标题来保存md5总和。 – PiQuer 2014-08-19 10:03:06
对于分段上传,ETag似乎不是MD5(按照Gael Fraiteur的评论)。在这些情况下,它包含一个减号和一个数字的后缀。然而,即使是减号之前的位似乎也不是MD5,即使它与MD5的长度相同。后缀可能是上传的零件数量?
此后缀似乎只在文件较大(大于5GB)时才会显示。通过检查我拥有的大量文件,看起来后缀代表上传的部分数量。但是,第一部分似乎没有与原始文件相同的md5散列。在计算这个散列时,亚马逊必须为每个部分折叠一些额外的数据。我想知道该算法,以便我可以检查一些文件。 – 2012-08-29 19:19:12
哈希算法在这里描述:http://stackoverflow.com/questions/6591047/etag-definition-changed-in-amazon-s3 – Nakedible 2014-09-04 22:02:35
我已经交叉检查jets3t和管理控制台上传文件的MD5sum,并且ETag似乎等于MD5sum。你可以查看文件的属性在AWS管理控制台:
这对我的作品。 在PHP中,你使用这个可以比较本地文件Ë亚马逊文件的校验:
// 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不一样的ETag的S3。
ETag会根据数据卡盘计算并concat所有md5hash再次进行md5哈希,并将块数保留在最后。
这里是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;
}
的ETag
AWS的文件说:
实体标记为对象的哈希值。 ETag仅反映对象内容的变化,而不反映其元数据。 ETag可能是也可能不是对象数据的MD5摘要。不论它是取决于对象是如何创建的,以及如何,如下所述加密:由PUT物件,POST对象或复制操作创建
- 对象,或通过AWS管理控制台,并且是由SSE-S3或明文加密,具有ETags,它们是对象数据的MD5摘要。
- 由PUT对象,POST对象或复制操作或通过AWS管理控制台创建并由SSE-C或SSE-KMS加密的对象具有不是其对象数据的MD5摘要的ETags。
- 如果通过分段上载或部分复制操作创建对象,则无论采用何种加密方法,ETag都不是MD5摘要。
参考:http://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonResponseHeaders.html
这里是代码即可获得MD5哈希按照2017年
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);
}
}
注释代码是大多数人把它错误的将其更改为十六进制
下面是从c#转换为PowerShell中的对象获取S3 ETag的代码。
function Get-ETag {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$Path,
[Parameter(Mandatory=$true)]
[int]$ChunkSizeInMb
)
$returnMD5 = [string]::Empty
[int]$chunkSize = $ChunkSizeInMb * [Math]::Pow(2, 20)
$crypto = New-Object System.Security.Cryptography.MD5CryptoServiceProvider
[int]$hashLength = $crypto.HashSize/8
$stream = [System.IO.File]::OpenRead($Path)
if($stream.Length -gt $chunkSize) {
$chunkCount = [int][Math]::Ceiling([double]$stream.Length/[double]$chunkSize)
[byte[]]$hash = New-Object byte[]($chunkCount * $hashLength)
$hashStream = New-Object System.IO.MemoryStream(,$hash)
[long]$numBytesLeftToRead = $stream.Length
while($numBytesLeftToRead -gt 0) {
$numBytesCurrentRead = [int][Math]::Min($numBytesLeftToRead, $chunkSize)
$buffer = New-Object byte[] $numBytesCurrentRead
$numBytesLeftToRead -= $stream.Read($buffer, 0, $numBytesCurrentRead)
$tmpHash = $crypto.ComputeHash($buffer)
$hashStream.Write($tmpHash, 0, $hashLength)
}
$returnMD5 = [System.BitConverter]::ToString($crypto.ComputeHash($hash)).Replace("-", "").ToLower() + "-" + $chunkCount
}
else {
$returnMD5 = [System.BitConverter]::ToString($crypto.ComputeHash($stream)).Replace("-", "").ToLower()
}
$stream.Close()
$returnMD5
}
- 1. ios上传文件到亚马逊s3
- 2. 亚马逊S3文件上传
- 3. 亚马逊S3文件上传
- 4. 上传文件到亚马逊s3
- 5. 无法获得Carrierwave与亚马逊S3
- 6. 如何从亚马逊S3
- 7. android亚马逊s3上传
- 8. zcat上亚马逊s3
- 9. 解压亚马逊S3中的文件
- 10. 亚马逊S3中的重复文件
- 11. 如何列出上传的文件到亚马逊s3
- 12. 亚马逊S3和MP4文件
- 13. 亚马逊s3文件从android下载
- 14. 亚马逊S3丢失文件
- 15. 亚马逊S3查看文件
- 16. 如何创建和上传文件到亚马逊S3
- 17. 如何将文件上传到亚马逊S3从Android
- 18. Android的亚马逊S3 TransferUtility
- 19. 亚马逊S3 :: noSuchKeyError上的重定向
- 20. 亚马逊的Java SDK - 上传到S3
- 21. 从亚马逊S3删除
- 22. 亚马逊s3桶ListObject
- 23. Rails和亚马逊S3
- 24. 离线亚马逊S3
- 25. 亚马逊EC2和S3
- 26. 亚马逊S3(AWS)NSMutableData
- 27. 亚马逊S3虾PDF
- 28. 亚马逊S3到期日?
- 29. 亚马逊S3和android
- 30. ColdFusion ImageWrite到亚马逊S3
ETag头是MD5,但不适用于多部分文件。以下是关于如何使用它的更多信息:http://stackoverflow.com/questions/6591047/etag-definition-changed-in-amazon-s3/31086810#31086810 – r03 2015-07-21 19:35:59
考虑改变对这个问题的接受答案,因为人谁不读下面的评论和答案将被误导。 – JLo 2016-05-17 15:41:04