V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
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 · 2018-05-08 10:25:27 +08:00 · 3626 次点击
    这是一个创建于 2399 天前的主题,其中的信息可能已经有所发展或是发生改变。

    例如:

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

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

    第 1 条附言  ·  2018-05-09 10:10:22 +08:00
    其实是不限于两个 json 字符比较,两个 json 字符串经过一系列加密成两个字符串,比较两个加密后的字符串相等来确定两个 json 字符串相等也行。
    31 条回复    2018-05-10 09:59:40 +08:00
    lihongjie0209
        1
    lihongjie0209  
       2018-05-08 10:28:51 +08:00
    举个反例我看看哪里不相等.
    myyou
        2
    myyou  
    OP
       2018-05-08 10:32:37 +08:00
    @lihongjie0209 对于 {"a":1, "b":2} js 和 python 得到的 json 字符串不相等
    myyou
        3
    myyou  
    OP
       2018-05-08 10:33:53 +08:00
    @lihongjie0209 所以我希望能把 json 数据转化为一个相等的字符串,并不一定是 json 字符串
    ylcc
        4
    ylcc  
       2018-05-08 10:35:34 +08:00
    你确定得到的 json 字符串不一样么。。。
    lihongjie0209
        5
    lihongjie0209  
       2018-05-08 10:39:19 +08:00
    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
        6
    myyou  
    OP
       2018-05-08 10:48:52 +08:00
    @ylcc
    @lihongjie0209
    好吧,我错了,那天测试是不一样的,可能是幻觉吧
    mulog
        7
    mulog  
       2018-05-08 10:51:18 +08:00
    什么叫「 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
        8
    lihongjie0209  
       2018-05-08 10:53:39 +08:00
    @myyou #6 作为一个数据传输格式, 你没必要关注字符串是否一样, 只需要关注在转换在相应语言中的 map 或者对象的时候里面的数据是否一致就好了. 字符串只是信息的一种表达形式.
    momocraft
        9
    momocraft  
       2018-05-08 11:02:42 +08:00
    json 不稳定的地方只有 object key 的顺序。在各语言用 json-stable-stringify (npm) 这样的库然后调到一致就行了。
    myyou
        10
    myyou  
    OP
       2018-05-08 11:06:35 +08:00
    @momocraft 对我就是希望 key 的顺序也一样
    ipwx
        11
    ipwx  
       2018-05-08 11:22:58 +08:00
    @myyou Python: json.dumps(..., sort_keys=True)

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

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

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

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

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

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

    在可控的环境下可以考虑,要对任意情况下都能解决,对楼主来说可能有点困难了。
    yzmm
        26
    yzmm  
       2018-05-09 10:00:54 +08:00
    json 只是数据格式,比较还得自己写转换,不能混为一谈吧。
    myyou
        27
    myyou  
    OP
       2018-05-09 10:05:27 +08:00
    @vimiix MD5 怎么校验?怎样把不同语言产生的 json 字符串生成相同 MD5 ?有没有办法没?
    myyou
        28
    myyou  
    OP
       2018-05-09 10:05:59 +08:00
    @yzmm 有没有好的转化方法没?
    mayorbryant
        29
    mayorbryant  
       2018-05-09 11:15:04 +08:00
    感觉你说的跟验签差不多,不管是 js 还是 Python 来的 json 数据,你要验证是否为同一个 string?那就在 js 和 Python 保持格式一致啊,不管是用 json.dumps 还是自己写一个方法,比如说按照 key 的升序以'key=value&'拼接
    towl
        30
    towl  
       2018-05-09 20:25:06 +08:00
    没看明白是啥意思,看了评论,大概是找有序字典? 如果是这样的话,建议使用 python 内置模块 collections.OrderedDict
    myyou
        31
    myyou  
    OP
       2018-05-10 09:59:40 +08:00
    @towl 不是有序字典,是希望不论哪种编程语言,通过一定算法把 json 转为一个字符串,通过比较字符串就能确认两个 json 是否相等
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2599 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 03:05 · PVG 11:05 · LAX 19:05 · JFK 22:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.