有人知道在rails 5.2 +上使用ActiveStorage时如何计算active_storage_blobs中的校验和字段?
对于奖励积分,是否有人知道我如何使用md5校验和来匹配md5 CLI命令中的校验和?
答案 0 :(得分:2)
这是blob数据的base64编码的MD5摘要。我担心Active Storage不支持像md5(1)发出的十六进制校验和。遗憾!
答案 1 :(得分:2)
源代码在这里:https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/blob.rb#L234
def compute_checksum_in_chunks(io)
Digest::MD5.new.tap do |checksum|
while chunk = io.read(5.megabytes)
checksum << chunk
end
io.rewind
end.base64digest
end
在我的项目中,我需要使用此校验和值来判断用户是否上传了重复的文件,我使用以下代码通过上述方法获得相同的值:
md5 = Digest::MD5.file(params[:file].tempfile.path).base64digest
puts "========= md5: #{md5}"
输出:
========= md5: F/9Inmc4zdQqpeSS2ZZGug==
数据库数据:
pry(main)> ActiveStorage::Blob.find_by(checksum: 'F/9Inmc4zdQqpeSS2ZZGug==')
ActiveStorage::Blob Load (2.7ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."checksum" = $1 LIMIT $2 [["checksum", "F/9Inmc4zdQqpeSS2ZZGug=="], ["LIMIT", 1]]
=> #<ActiveStorage::Blob:0x00007f9a16729a90
id: 1,
key: "gpN2NSgfimVP8VwzHwQXs1cB",
filename: "15 Celebrate.mp3",
content_type: "audio/mpeg",
metadata: {"identified"=>true, "analyzed"=>true},
byte_size: 9204528,
checksum: "F/9Inmc4zdQqpeSS2ZZGug==",
created_at: Thu, 29 Nov 2018 01:38:15 UTC +00:00>
答案 2 :(得分:1)
我知道我参加聚会有点晚了,但这对于那些在寻找答案的过程中遇到的人来说更是如此。所以就在这里。
背景:
Rails在5.2版中引入了许多新功能,其中之一是 ActiveStorage 。官方最终版本于2018年4月9日发布。
免责声明:
因此,非常清楚地说,以下信息与现成的 vanilla 主动存储有关。这也没有考虑到一些疯狂的代码功能,这些代码功能围绕某个关闭场景进行。
话虽如此,根据您的Active Storage设置,校验和的计算方式有所不同。使用香草的现成可用的Rails Active Storage,有2种“类型”(由于缺乏更好的术语)。
文件上传流程: [客户端]→[RoR应用]→[存储服务]
Comm。流程: 可以有所不同,但在大多数情况下,应类似于文件上传流程。
SparkBao的答案中上面指出的是“代理上传”。这意味着您将文件上传到RoR应用程序并执行某种处理,然后再将文件发送到配置的存储服务(AWS,Azure,Google,BackBlaze等...)。即使您将存储服务设置为“ localdisk”,即使RoR应用程序是存储端点,该逻辑在技术上仍然适用。
“ 代理上传”方法不适用于在Heroku等服务上的云中部署的RoR应用程序。 Heroku有30秒的硬性限制,可以完成交易并将响应发送回客户(最终用户)。因此,如果文件很大,则需要考虑文件上传所需的时间,然后考虑计算校验和的时间。如果您遇到无法在30秒内完成请求的响应的情况,则需要使用“ 直接上传”方法。
代理上传答案:
Spark.Bao指出的方法Digest::MD5中使用了Ruby类compute_checksum_in_chunks(io)。
文件上传流程: [客户端]→[存储服务]
Comm。流程: [客户端]→[RoR App]→[客户端]→[存储服务]→[客户端]→[RoR App]→[客户端]
我们维护和开发Rails的好朋友已经为我们完成了所有繁重的工作。我不会详细介绍如何设置直接上传,但是这里是有关»Rails EdgeGuide - Direct Uploads的链接。
代理上传答案:
现在说了这么多,借助开箱即用的“ 直接上传”设置,可以利用SparkMD5(JavaScript)计算文件校验和。>
下面是Rails Active Storage Source Code- (activestorage.js)
中的摘录
var fileSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
var FileChecksum = function() {
createClass(FileChecksum, null, [ {
key: "create",
value: function create(file, callback) {
var instance = new FileChecksum(file);
instance.create(callback);
}
} ]);
function FileChecksum(file) {
classCallCheck(this, FileChecksum);
this.file = file;
this.chunkSize = 2097152;
this.chunkCount = Math.ceil(this.file.size / this.chunkSize);
this.chunkIndex = 0;
}
createClass(FileChecksum, [ {
key: "create",
value: function create(callback) {
var _this = this;
this.callback = callback;
this.md5Buffer = new sparkMd5.ArrayBuffer();
this.fileReader = new FileReader();
this.fileReader.addEventListener("load", function(event) {
return _this.fileReaderDidLoad(event);
});
this.fileReader.addEventListener("error", function(event) {
return _this.fileReaderDidError(event);
});
this.readNextChunk();
}
},
如果有什么我想念的事,我会提前致歉。我试图做到尽可能彻底。
因此,总而言之,以下内容足以作为可接受的答案:
代理上传配置: ruby类Digest::MD5
直接上传配置: :JavaScript哈希库SparkMD5。
答案 3 :(得分:0)
关于奖金问题(可能也是主要问题):
您可以将校验和从base64转换为十六进制(例如md5(1)命令支持)并返回。
Converting a hexadecimal digest to base64 in Ruby:
def hex_to_base64(hexdigest)
Base64.strict_encode64([hex_string].pack("H*"))
end
从base64到十六进制:
def base64_to_hex(base64_string)
Base64.decode64(base64_string).each_byte.map { |b| "%02x" % b.to_i }.join
end