V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
BenchWidth
V2EX  ›  问与答

一个关于我的同事计算 md5 的问题!

  •  
  •   BenchWidth · 339 天前 · 13925 次点击
    这是一个创建于 339 天前的主题,其中的信息可能已经有所发展或是发生改变。
    由于项目的设计需要项目中资源上传的时候都是需要上传 md5 来校验文件,我是负责的网页前端与 java 后端部分的。

    昨天,ios 端的兄弟说有时候文件上传之后有时候地址是不能访问的(公司用的阿里云 oss )。我去看了一些发现了文件名有许多的奇奇怪怪的字符,被后台替换为空格了。我问了一些 ios 的兄弟他说的是算出来的 md5 值。我也问了一下安卓的兄弟,发现我们三端计算出来的文件 md5 都有自己的格式。(我自己写的前端和后端的计算方法得出的都是一样的 md5 )

    前端,java 后台:2cf8510722f63a433865b7b244738b22
    安卓:fuo0n0ga3rfs9qo5dd5qdmq8c
    ios:Z L6tJUcklneku8zMPoqcw==

    前端和 java 后台是我自己写所以怎么算都是一样的。主要是安卓和 iso 他们和我说编程语言不一样算出来的就是不一样的,而且 ios 他说没法算出我这种 md5 数值。

    我想的是 md5 难道不都是通过获取文件的二进制流再进行一系列的算法得出的一个固定的值嘛,难道说在不同的地方读取出来的文件二进制流不一样?或者说是使用的算法不一样?还是说只是他们没有找到方法而已?还是说是我自己算错了。

    大佬们,解决一下我的疑问吧!!!!!
    第 1 条附言  ·  338 天前
    附个言

    找了个新的文件又各个端计算了一次
    md5sum :c0724e99bef703ff443971d4d07785d2
    java :c0724e99bef703ff443971d4d07785d2
    安卓 : 60e979jfnn0fvk8ebhqj87f1ei
    ios : wHJOmb73A/9EOXHU0HeF0g==

    经过各位大佬的评论我一个个去尝试了一些找出了问题所在。

    我计算的 md5 是能和 linux 的 md5sum 对的上。没什么问题。

    安卓的 md5 是将 16 进制转换为了 32 进制。大文件计算的时候似乎没有将文件读取完就进行了 md5 计算。所以小文件得出的 md5 进行 16 进制转换后能与我的 md5 相对。大文件就对不上了。

    ios 的 md5 这个就要多谢#120 的老哥了。ios 是将算出来的 16 进制 32 位的 md5 进行了 10 进制转换,再将 10 进制转换为了 ASCII 对应的字符。再将得到的字符串进行了 base64 编码。(大文件也有对不上的问题)
    134 条回复    2020-12-25 10:56:25 +08:00
    1  2  
    baijiahei
        1
    baijiahei   339 天前
    同一文件 md5 值相同
    ios 端的看起来像 base64 后的 然后还有个空格 可能+号 后台接收的时候给过滤掉了
    说不好 但是 ios 端的肯定是不对的
    binbinyouliiii
        2
    binbinyouliiii   339 天前
    你让他拿个简单字符算一下对比一下不就完了
    ThirdFlame
        3
    ThirdFlame   339 天前
    md5 值 是 16*8=128bit
    前端和 java 显示的是 hex 格式显示的。
    ios 貌似是 base64 编码后显示的(不过也和 前端和 java 算的不一样)

    同一个文件计算出来的 md 值( 128bit )是相同的,这是毋庸置疑的。
    SjwNo1
        4
    SjwNo1   339 天前
    啊哈 不同的编程语言 md5 算法不一样吗 坐等楼下解答
    louiswang002
        5
    louiswang002   339 天前 via iPhone
    可能 iOS 端用了阿里云的工具类算出来的 md5,那个工具类里面有个函数,是 md5 之后 base64,这个值可以用于阿里云 oss 校验,可以让 iOS 的同事 review 代码
    maro
        6
    maro   339 天前   ❤️ 11
    一个 32 位 一个 24 位 一个干脆是 base64
    whileFalse
        7
    whileFalse   339 天前   ❤️ 12
    都按照 linux 下的 md5sum 对齐,谁算出来和 md5sum 不一致就打回去重写
    paullee
        8
    paullee   339 天前   ❤️ 1
    啊,你们缺少有话语权的人,这玩意儿能算出 3 个版本,那你们其他业务的坑恐怕只多不少。建议参照 7 楼的建议。
    Citrus
        9
    Citrus   339 天前   ❤️ 70
    安卓和 iso 他们和我说编程语言不一样算出来的就是不一样的

    建议把说这话的人开掉。
    msg7086
        10
    msg7086   339 天前
    Z+L6tJUcklneku8zMPoqcw==
    对应的 hex 是
    67e2fab4951c9259de92ef3330fa2a73
    和你算出来的不一样。

    至于谁对谁错,各家 hash 工具解忧愁。
    f6x
        11
    f6x   339 天前
    @whileFalse 你歧视其他操作系统. 命名 mac 和 win 下也有 md5sum
    longaiwp
        12
    longaiwp   339 天前   ❤️ 1
    你管它哪个对哪个错,就按照 Linux 下的 md5sum 来,谁不一样就谁回去研究重写。
    SjwNo1
        13
    SjwNo1   339 天前   ❤️ 5
    重点关照下这位 ios 同学,胡言乱语
    ssynhtn
        14
    ssynhtn   339 天前
    这两个客户端都很优秀啊, 都是自己实现 md5 算法
    一般菜鸟都是网上找一段代码复制粘贴一下
    Rehtt
        15
    Rehtt   339 天前
    @f6x md5sum 本来最先出现在 linux 中,mac 和 win 都可以说是移植的
    longaiwp
        16
    longaiwp   339 天前
    另外你们这位做 iOS 的人,估计技术不过关,建议要他多学习。
    keepeye
        17
    keepeye   339 天前
    你到网上找个 swift 的标准 MD5 算法扔给他。我估计他连 md5 是什么都不知道
    BenchWidth
        18
    BenchWidth   339 天前
    @ssynhtn 他就是网上找的计算 md5 的方式。。也不晓得哪儿找的(这就很头大了)
    BenchWidth
        19
    BenchWidth   339 天前
    @keepeye 我扔了一个 md5 标准算法,他说什么 ios 不能根据文件夹获取文件啥的,就是似乎拿不到文件的二进制流。。我也不懂 ISO 就没说什么了。
    BenchWidth
        20
    BenchWidth   339 天前
    @Citrus 好残忍,哈哈哈
    keepeye
        21
    keepeye   339 天前
    @BenchWidth 怎么可能无法读取呢?
    BenchWidth
        22
    BenchWidth   339 天前   ❤️ 1
    @louiswang002 他在 csdn 找的代码只有 10 几行。。。
    liushaokang
        23
    liushaokang   339 天前
    哈哈哈哈哈,没想到还会有这种问题
    misaka19000
        24
    misaka19000   339 天前
    四五年前有幸和做 iOS 的人打过交道,那些人的水平真是菜
    imdong
        25
    imdong   339 天前   ❤️ 7
    让我想起之前一个同事,让他做一个上传文件去重的功能,一个星期过去了,没动静,过去一问,搞不定,不知道咋弄...

    我说用 md5 啊,你把上传的文件 md5 存数据库,每次上传检查数据库有么有记录嘛。

    他说好,然后又一个星期过去了,我问咋样了...他说每次上传的文件 md5 都不一样。

    我一看代码,呵:

    ```PHP

    md5($file_name);

    ```

    对不懂 PHP 的朋友们一个提示

    `md5 ( string $str [, bool $raw_output = false ] ) : string`

    我...后来他试用期没过,听说去了 OPPO,唉...
    Rwing
        26
    Rwing   339 天前
    md5 是标准算法。。。。各语言肯定是一样的,如果不一样,说明有人错了。。。。
    BenchWidth
        27
    BenchWidth   339 天前
    @keepeye 不知道,,我也很纳闷,我现在特别的懵逼。。。。毕竟我没写过 iOS 。昨天他解释的就是说 ISO 与安卓读取文件的方式不一样,什么什么文件拿不到之类的。我问他能到文件的二进制流嘛,他就说 iOS 啥的(不懂不懂听不懂!)
    zhangxiaoming
        28
    zhangxiaoming   339 天前
    跟楼主一模一样的情况,最近一个月多起来的,软件批量搞的根本防不住。当看不见...
    zhangxiaoming
        29
    zhangxiaoming   339 天前
    @zhangxiaoming
    不好意思回错帖子了...
    RayJiang9
        30
    RayJiang9   339 天前
    如果 iOS 用的 Swift 的话,直接引入这个库,内置了多种算法 [CryptoSwift]( https://github.com/krzyzanowskim/CryptoSwift)
    不过还是建议开除 iOS
    BenchWidth
        31
    BenchWidth   339 天前
    @RayJiang9 哈哈哈哈,你们好残忍
    YouLMAO
        33
    YouLMAO   339 天前 via Android
    老板发话了,算出正确 md5 的年终奖 10 个比特币,算错了倒扣 2 个,他们工资高让他们算
    Woood
        34
    Woood   339 天前
    他就说 iOS 啥的(不懂不懂听不懂!)
    莫名有看孔乙己的感觉
    oneisall8955
        35
    oneisall8955   339 天前
    用脚想都知道能算一致的
    yaocai321
        36
    yaocai321   339 天前
    建议看了下 md5 的原理, 然后手写下, 花不了一天的时间
    gamexg
        37
    gamexg   339 天前
    Java 的是 hex 格式,ios 的是 base64 格式,

    但是谁能介绍下,安卓的是什么格式? 32 进制??
    des
        38
    des   339 天前
    建议开除,骗鬼呢
    louiswang002
        39
    louiswang002   339 天前 via iPhone
    @BenchWidth 告诉他用 NSData 读取文件,然后再用这个对象 MD5,再不行让他去 aliyunoss 里面找 OSSUtil 这个工具类,找 MD5 的方法
    way2explore2
        40
    way2explore2   339 天前
    @gamexg 同好奇
    cornetCat
        41
    cornetCat   339 天前
    建议开除,不然后续的坑你会吐血
    BenchWidth
        42
    BenchWidth   339 天前   ❤️ 2
    @gamexg 我刚看了看他的代码似乎把 16 进制转换成了 32 进,我重新找了 个文件。
    我算出来是 bfc918bf80386fa7f2784807c07860d8
    安卓算出来是 5vp4cbv01odujv4u280v07go6o
    他说他用的是安卓 sdk 的方法来获取的,不知道是不是被自动转成 32 进制了
    mxT52CRuqR6o5
        43
    mxT52CRuqR6o5   339 天前
    有啥好疑问的,那两位水平不行
    你看看他们是培训机构出来的还是科班出来的
    BenchWidth
        44
    BenchWidth   339 天前
    @louiswang002 好的
    hatebugs
        45
    hatebugs   339 天前 via Android
    这个水平,,
    vanxy
        46
    vanxy   339 天前
    @BenchWidth #42 Android 的看起来就不像 md5 呀

    搜索一下, 复制粘贴,5 分钟搞定:
    https://juejin.cn/post/6844903444810055687
    icyalala
        47
    icyalala   339 天前   ❤️ 13
    @Woood

    这 iOS 童鞋编译不报错了,涨红的脸色渐渐复了原,他人便又问道,“童鞋,你当真认会做 iOS ?” 他看着问他的人,显出不屑置辩的神气。他们便接着说道,“你怎的连 md5 都算不对呢?”他立刻显出颓唐不安模样,脸上笼上了一层灰色,嘴里说些话;这回可是全是 block runtime 之类,一些不懂了。在这时候,众人也都哄笑起来:工位前后充满了快活的空气。
    FreeEx
        48
    FreeEx   339 天前 via iPhone
    我的天,建议面试官辞职谢罪
    gefranks
        49
    gefranks   339 天前
    算不对还可以忍, 但是说编程语言不一样算出来的就是不一样的,建议开除。
    php01
        50
    php01   339 天前
    这水平能找到工作,是不是应该反省一下公司的招聘录用流程?
    superrichman
        51
    superrichman   339 天前 via iPhone
    安卓的可能是把 hmacmd5 当成 md5 用了
    Jackeriss
        52
    Jackeriss   339 天前 via iPhone
    今日最佳
    zszhere
        53
    zszhere   339 天前 via iPhone
    先统一 tohex()把格式整一致了再说
    如果还不一致就找个小文件做二进制的 bindiff
    zqx
        54
    zqx   339 天前 via Android
    md5 是一个给资源生成唯一标识的规则,不是具体算法吧,指定同一种算法,不同平台的结果肯定是一样的
    dogfood
        55
    dogfood   339 天前
    牛逼 class
    rigortek
        56
    rigortek   339 天前 via iPhone
    md5 都能有争议,还和语言有关?醉了!
    命令行一条 md5sum 结果就是三端看齐的标准
    iOS 绝对水货一个
    sampeng
        57
    sampeng   339 天前 via iPhone
    今日最佳
    我说这样的留着过年?
    richChou
        58
    richChou   339 天前
    想起之前公司有个开发跟我说不同语言 Base64 Encode 之后的值不一样。
    360511404
        59
    360511404   339 天前
    单看 iOS
    是不是跟你的结果一致,这个重要吗
    能得出这样的 md5 值的 iOS,你还留着过年吗
    他自己都不看一下自己的值,他不知道怎么看都铁定不是 md5 吗
    ztxcccc
        60
    ztxcccc   339 天前
    @zqx md5 就是算法名,还有 md4 之类的,你也要多学习
    1s1s
        61
    1s1s   339 天前
    不敢看不敢看
    djs
        62
    djs   339 天前
    直接好家伙,这辆端开发有毒
    glennv2ex
        63
    glennv2ex   339 天前
    前端,java 后台看起来没问题 安卓的 25 位肯定不对 ios 的更离谱了
    glennv2ex
        64
    glennv2ex   339 天前
    欺负你这个老后端😄
    BenchWidth
        65
    BenchWidth   339 天前
    @glennv2ex 哭了哭了,太难了
    guibin1989
        66
    guibin1989   339 天前
    iOS 程序员风评被害,建议开除。
    longaiwp
        67
    longaiwp   339 天前
    @richChou 确实会有,哪怕都是 Jawa,Android 和 Jawa 原生的 Base64 也会有不同,内部的规则问题。但是这本质上不是哪个语言不能得出哪个样子的东西,只要你指定要哪样的,一定能搞出来的。
    sss495088732
        68
    sss495088732   339 天前
    0.0 不用标准库自己写,去百度 CV?
    SjwNo1
        69
    SjwNo1   339 天前
    贵司的客户端能用吗哈哈
    heliotrope
        70
    heliotrope   339 天前
    @richChou 确实会不一样呀 字符编码 填充方式 都有可能不一样
    zjddp
        71
    zjddp   339 天前
    提问:这三人至少有几个人有问题
    huayumo
        72
    huayumo   339 天前
    哈哈哈,ios 的要笑死了
    local
        73
    local   339 天前
    这不至少 2 有问题吗
    FallenTy
        74
    FallenTy   339 天前
    建议换个 ios 。
    local
        75
    local   339 天前
    iOS 的看格式应该是 md5 后,又 base64 编码的结果
    sarices
        76
    sarices   339 天前
    md5 不是一般都是把结果生成 32 位十六进制数字吗,ios 和安卓是什么鬼算法
    dddz97
        77
    dddz97   339 天前
    说今日最佳的,我觉得是这周最佳
    pushback
        78
    pushback   339 天前
    这两端的年轻人不讲武德
    xloger
        79
    xloger   339 天前
    Android 的你建议他用 Guava 算了。之前项目里是拷网上的代码有 OOM 问题,然后我自己去搜了下,发现大多中文资料不太靠谱,想用 NIO 结果遇到了一些问题,试来试去最后上 Guava 了。

    参考资料:(我的参考顺序)
    <http://blog.atomicer.cn/2017/05/16/%E4%BD%BF%E7%94%A8nio%E7%9A%84%E5%86%85%E5%AD%98%E6%98%A0%E5%B0%84%E8%AE%A1%E7%AE%97%E8%B6%85%E5%A4%A7%E6%96%87%E4%BB%B6%E7%9A%84MD5/>
    <https://www.cnkirito.moe/file-io-best-practise/>
    <https://www.jianshu.com/p/f81073adc67d>
    <https://stackoverflow.com/questions/304268/getting-a-files-md5-checksum-in-java>
    ReysC
        80
    ReysC   339 天前
    安卓和 IOS 的应该好好查查文档,并且贴个 MD5 的正则验证:

    ^([a-z0-9]{32})$ 来自 https://regexlib.com/REDetails.aspx?regexp_id=698

    说真的,看到 o 和 u 的时候,已经不知道是啥东西了。HEX 怎么能超过 F

    附赠:

    https://en.wikipedia.org/wiki/MD5
    locoz
        81
    locoz   339 天前 via Android
    “主要是安卓和 ios 他们和我说编程语言不一样算出来的就是不一样的,而且 ios 他说没法算出我这种 md5 数值。”
    很真实哈哈哈哈哈,见过好几个做客户端开发的都有类似情况,主要可能是理解不了,因为和做客户端的那些东西不是一个逻辑。
    Elethom
        82
    Elethom   339 天前   ❤️ 2
    我来唱个反调,Android 和 iOS 端提供的 md5 都真的是 md5,不过 Android 是 32 进制的,iOS 的是 base64 encode 过的 raw data 。

    但是依然建议:
    - 开除这两位,不会转换标准 hex 字串留着过年?
    - 开除所有楼上说不是 md5 的,真的太鸡巴菜了
    JDog
        83
    JDog   339 天前
    我曾经一位 iOS 开发同事......

    我: “传参比较大,放 body 里吧”
    研究了半天以后....
    同事: “iOS 这边好像没法把参数放 body 里,就 URL 传参吧”


    我特么惊了,敢情 OC 实现的 http 协议没 body
    a719031256
        84
    a719031256   339 天前
    把 ios 开发打一顿就对了,这明显是搞事嘛
    Elethom
        85
    Elethom   339 天前 via iPhone
    @locoz
    iOS 自己的 crypto 库出来就是 raw data,直接输出字串就是 encode 过的,和语言没关系,和输出格式有关系。当然不会输出 hex 字串就是水平有问题,和「和做客户端的那些东西不是一个逻辑」没关系。
    liman
        86
    liman   339 天前
    牛逼!耳机可完全被认为了
    imdong
        87
    imdong   339 天前
    @ReysC 补一下,正则限定范围应该是:^[a-f0-9]{32}$

    仅限小写。
    wysnylc
        88
    wysnylc   339 天前
    @JDog #83 冷知识,get 也可以放 body,但是非标准实现服务端不保证能正常接收
    CatTom
        89
    CatTom   339 天前
    亲,这边建议您先去暴打一顿当初的面试官哟~
    zpf124
        90
    zpf124   339 天前
    @zqx hash 哈希摘要算法,是一个笼统的算法规则,而 md5,sha1 sha256 都是具体的哈希算法实现,是已经规定好了具体算法思路的,不论什么平台什么工具算出来的 md5 值都应该是一样的。
    zckevin
        91
    zckevin   339 天前
    啊这
    fanjianhang
        92
    fanjianhang   339 天前
    好家伙颠覆了
    lovecy
        93
    lovecy   339 天前
    @Elethom 我把楼主提供的 32 进制转成 16 进制,和他给的正确 md5 对不上啊。。
    shawnsh
        94
    shawnsh   339 天前 via Android
    水的一比,那大家换个 sha3 来校验吧,狗头
    ReysC
        95
    ReysC   339 天前
    没用过 32 进制的 md5,顺道补充知识。
    日常看到 md5 就默认是 16 进制 HEX 。

    多谢大佬 @Elethom 说明
    BenchWidth
        96
    BenchWidth   339 天前
    @xloger 好的,谢谢大佬!我发给他看看
    devcat
        97
    devcat   339 天前
    巧了,我也遇到同样的问题,就在前几天
    BenchWidth
        98
    BenchWidth   339 天前
    @lovecy 刚刚找到问题了,文件比较小的他计算出来的值转换为 16 进制刚好是可以和我的 md5 对上。大文件他计算出来的就有问题了,
    JKeita
        99
    JKeita   339 天前
    ios 那个是 MD5 ?你在搞笑?
    JKeita
        100
    JKeita   339 天前
    MD5 是规范好吧,不同语言算出来的都应该一样。
    1  2  
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1586 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 00:15 · PVG 08:15 · LAX 16:15 · JFK 19:15
    ♥ Do have faith in what you're doing.