推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
myyou
V2EX  ›  Python

有没有办法让每一个 json 数据转为与之对应的字符串,而且对于 Python , Java 和 js 等语言都通用且转化的字符串也相等?

  •  
  •   myyou · May 8, 2018 · 4916 views
    This topic created in 3107 days ago, the information mentioned may be changed or developed.

    例如:

    {"a": "数据 1", "b": ["测试 1", "测试 2"]}
    

    这样的数据转为一个字符串,对于多数语言通用,且各个语言转化的字符串相等,最好是可逆的。

    Supplement 1  ·  May 9, 2018
    其实是不限于两个 json 字符比较,两个 json 字符串经过一系列加密成两个字符串,比较两个加密后的字符串相等来确定两个 json 字符串相等也行。
    31 replies  •  2018-05-10 09:59:40 +08:00
    lihongjie0209
    lihongjie0209
    May 8, 2018
    1
    举个反例我看看哪里不相等.
    myyou
    myyou
    OP
    May 8, 2018
    2
    @lihongjie0209 对于 {"a":1, "b":2} js 和 python 得到的 json 字符串不相等
    myyou
    myyou
    OP
    May 8, 2018
    3
    @lihongjie0209 所以我希望能把 json 数据转化为一个相等的字符串,并不一定是 json 字符串
    ylcc
    ylcc
    May 8, 2018
    4
    你确定得到的 json 字符串不一样么。。。
    lihongjie0209
    lihongjie0209
    May 8, 2018
    5
    js:

    obj = {"a":1, "b":2}
    {a: 1, b: 2}
    JSON.stringify(obj)
    "{"a":1,"b":2}"



    python:

    In [1]: obj = {"a": 1, "b": 2}

    In [2]: import json

    In [3]: s = json.dumps(obj)

    In [4]: print(s)
    {"a": 1, "b": 2}

    In [5]:



    @myyou 哪里不一样
    myyou
    myyou
    OP
    May 8, 2018
    6
    @ylcc
    @lihongjie0209
    好吧,我错了,那天测试是不一样的,可能是幻觉吧
    mulog
    mulog
    May 8, 2018
    7
    什么叫「 json 数据转换成对应的字符串」? json 数据不是字符串还能是啥。。。
    我猜一下,你是想问:
    有 json 字符串 s, 如何使得 dump_to_json(load_from_json(s)) === s, 对于所有语言?
    这个我觉得主要是格式控制吧,比如 python:json.dumps(obj, separators=(',', ':')) 就没有空格了。
    https://stackoverflow.com/questions/16311562/python-json-without-whitespaces
    lihongjie0209
    lihongjie0209
    May 8, 2018
    8
    @myyou #6 作为一个数据传输格式, 你没必要关注字符串是否一样, 只需要关注在转换在相应语言中的 map 或者对象的时候里面的数据是否一致就好了. 字符串只是信息的一种表达形式.
    momocraft
    momocraft
    May 8, 2018
    9
    json 不稳定的地方只有 object key 的顺序。在各语言用 json-stable-stringify (npm) 这样的库然后调到一致就行了。
    myyou
    myyou
    OP
    May 8, 2018
    10
    @momocraft 对我就是希望 key 的顺序也一样
    ipwx
    ipwx
    May 8, 2018
    11
    @myyou Python: json.dumps(..., sort_keys=True)

    JS 不知道,别问我。
    Felldeadbird
    Felldeadbird
    May 8, 2018
    12
    不明白楼主遇到什么问题。
    "b" : 1
    "c" : "2"
    前者肯定会是数字,后者肯定是字符串的。 难道楼主在开发的时候,1 转换过来成了字符串?
    ipwx
    ipwx
    May 8, 2018
    13
    @lihongjie0209 @Felldeadbird

    Python 3.0 的字典字面量是 OrderedDict,所以 iter({"a":..., "b":...}) 永远返回 ["a","b"] 这个顺序。

    但是 json 反序列化得到的字典是 dict,iter(...) 顺序不固定。

    其他语言我不懂,不过也许也存在这个问题。这就是楼主的困扰。Python 的解决方案我上面已经给出了。

    @lihongjie0209 有时候比较 JSON 字符串是一种比较对象的快速方法。虽然 in general 不可靠,但是如果限定数据只有 ASCII 字符和整数,还是挺好用的。
    VoidChen
    VoidChen
    May 8, 2018
    14
    你是在问序列化吗
    ebingtel
    ebingtel
    May 8, 2018
    15
    不能……一是顺序不确定,而是有的加空格 有的不加
    lihongjie0209
    lihongjie0209
    May 8, 2018
    16
    @ipwx #13 就 json 而言, 是没有顺序一说的, 至于 python 怎么实现那是 python 的问题, 只要保证里面数据一样就可以
    myyou
    myyou
    OP
    May 8, 2018
    17
    @Felldeadbird 不是我是希望无论是 python 还是 js 处理得到的 json 字符串,直接通过比较字符串是否相等就能判断两个 json 是否相等,应为我想把一组 json 字符串当做一个标签来用
    momocraft
    momocraft
    May 8, 2018
    18
    #9 的补充:想了想字符串 (的 escape) 也有可能不稳定。还是要测试。
    lihongjie0209
    lihongjie0209
    May 8, 2018
    19
    @myyou #17 那你还不如用 mongodb 之类的文档数据库, 直接比较字符串是最不可取的方式
    Felldeadbird
    Felldeadbird
    May 8, 2018
    20
    如果你直接拿到 JSON 字符串来比较,那么两边语言 在收到对方传递过来的 JSON 字符串,你不反序列化,直接比较就可以了。 除非你是 一边语言是传递 JSON 字符串,一边语言从数据库或其他地方取出验证 JSON。那么直接比较必然会存在差异的。
    如果真的要比较,你需要在某一语言重组 JSON 结构顺序。 最近我有一个功能是 PHP 和 JS 的 JSON 比较,我是怎么实现是否一致的。
    vimiix
    vimiix
    May 8, 2018
    21
    为啥要比较 Json 字符串是否相等,json 字符串的大小太不可控了。
    具体不知道你是什么应用,但可以考虑使用 MD5 验证是否一致
    Trim21
    Trim21
    May 8, 2018 via Android
    22
    @ipwx 3.6 之前的不是有序的,3.6 之后的才是有序的 而且以后可能变回无序
    lolizeppelin
    lolizeppelin
    May 8, 2018 via Android
    23
    典型前端思路 怎么方便怎么来
    不就是想直接拿 string 相等来判断么
    srlp
    srlp
    May 8, 2018 via iPhone
    24
    序列化成字符串的时候把 key 排序、多余空格去掉、注释删掉即可,基本可以保证是相等的。

    不过这种结构化的东西,本来就应该结构化地比较,用字符串来比较看起来不是正道。
    srlp
    srlp
    May 8, 2018 via iPhone
    25
    另外,按照 key 排序这一点,不同编程语言的排序定义可能不一样,非 ascii 的字符怎么排这个也要定好,等等,还是有很多要注意的。

    在可控的环境下可以考虑,要对任意情况下都能解决,对楼主来说可能有点困难了。
    yzmm
    yzmm
    May 9, 2018
    26
    json 只是数据格式,比较还得自己写转换,不能混为一谈吧。
    myyou
    myyou
    OP
    May 9, 2018
    27
    @vimiix MD5 怎么校验?怎样把不同语言产生的 json 字符串生成相同 MD5 ?有没有办法没?
    myyou
    myyou
    OP
    May 9, 2018
    28
    @yzmm 有没有好的转化方法没?
    mayorbryant
    mayorbryant
    May 9, 2018
    29
    感觉你说的跟验签差不多,不管是 js 还是 Python 来的 json 数据,你要验证是否为同一个 string?那就在 js 和 Python 保持格式一致啊,不管是用 json.dumps 还是自己写一个方法,比如说按照 key 的升序以'key=value&'拼接
    towl
    towl
    May 9, 2018
    30
    没看明白是啥意思,看了评论,大概是找有序字典? 如果是这样的话,建议使用 python 内置模块 collections.OrderedDict
    myyou
    myyou
    OP
    May 10, 2018
    31
    @towl 不是有序字典,是希望不论哪种编程语言,通过一定算法把 json 转为一个字符串,通过比较字符串就能确认两个 json 是否相等
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1196 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 59ms · UTC 17:43 · PVG 01:43 · LAX 09:43 · JFK 12:43
    ♥ Do have faith in what you're doing.