簡體   English   中英

在python中解碼base64 guid

[英]decoding base64 guid in python

我正在嘗試在 python 中將 base64 字符串轉換回 GUID 樣式的十六進制數並且遇到問題。

Base64 編碼的字符串是: bNVDIrkNbEySjZ90ypCLew==

我需要把它恢復到: 2243d56c-0db9-4c6c-928d-9f74ca908b7b

我可以使用以下 PHP 代碼來完成,但無法在 Python 中解決

function Base64ToGUID($guid_b64) {
    $guid_bin = base64_decode($guid_b64);

    return join('-', array(
      bin2hex(strrev(substr($guid_bin, 0, 4))),
      bin2hex(strrev(substr($guid_bin, 4, 2))),
      bin2hex(strrev(substr($guid_bin, 6, 2))),
      bin2hex(substr($guid_bin, 8, 2)),
      bin2hex(substr($guid_bin, 10, 6))
    ));
  }

這是 GUIDtoBase64 版本:

function GUIDToBase64($guid) {
    $guid_b64 = '';
    $guid_parts = explode('-', $guid);

    foreach ($guid_parts as $k => $part) {
      if ($k < 3)
        $part = join('', array_reverse(str_split($part, 2)));

      $guid_b64 .= pack('H*', $part);
    }

    return base64_encode($guid_b64);
  }

以下是使用一些明顯和不那么明顯的選項的一些結果:

import base64
import binascii
>>> base64.b64decode("bNVDIrkNbEySjZ90ypCLew==")
'l\xd5C"\xb9\rlL\x92\x8d\x9ft\xca\x90\x8b{'
>>> binascii.hexlify(base64.b64decode("bNVDIrkNbEySjZ90ypCLew=="))
'6cd54322b90d6c4c928d9f74ca908b7b'

現有函數的 Python 端口(需要位

import bitstring, base64

def base64ToGUID(b64str):
  s = bitstring.BitArray(bytes=base64.b64decode(b64str)).hex
  def rev2(s_):
    def chunks(n):
      for i in xrange(0, len(s_), n):
          yield s_[i:i+n]
    return "".join(list(chunks(2))[::-1])
  return "-".join([rev2(s[:8]),rev2(s[8:][:4]),rev2(s[12:][:4]),s[16:][:4],s[20:]])

assert base64ToGUID("bNVDIrkNbEySjZ90ypCLew==") == "2243d56c-0db9-4c6c-928d-9f74ca908b7b"

首先,如果我們正確解碼,b64 字符串和生成的 GUID 不匹配。

>>> import uuid
>>> import base64
>>> u = uuid.UUID("2243d56c-0db9-4c6c-928d-9f74ca908b7b")
>>> u
UUID('2243d56c-0db9-4c6c-928d-9f74ca908b7b')
>>> u.bytes
'"C\xd5l\r\xb9Ll\x92\x8d\x9ft\xca\x90\x8b{'
>>> base64.b64encode(u.bytes)
'IkPVbA25TGySjZ90ypCLew=='
>>> b = base64.b64decode('bNVDIrkNbEySjZ90ypCLew==')
>>> u2 = uuid.UUID(bytes=b)
>>> print u2
6cd54322-b90d-6c4c-928d-9f74ca908b7b

您發布的結果 GUID 的 base64 編碼版本是錯誤的。 我不確定我是否理解您首先對 GUID 進行編碼的方式。

Python 擁有您能夠回答這個問題所需的所有工具。 但是,這是我在 python 終端中進行的粗略處理:

import uuid
import base64

base64_guid = "bNVDIrkNbEySjZ90ypCLew=="
bin_guid = base64.b64decode(base64_guid)
guid = uuid.UUID(bytes=bin_guid)
print guid

這段代碼應該給你足夠的提示來構建你自己的函數。 不要忘記,python shell 為您提供了一個強大的工具來測試和玩弄代碼和想法。 我會使用IPython notebooks 之類的東西進行調查。

我需要這樣做來解碼從 Mongodb 轉儲的 BASE64 UUID。 最初該領域是由貓鼬創建的。 我使用的代碼基於@tpatja 的代碼,在這里:

def base64ToGUID(b64str):
  try:
    bytes=base64.urlsafe_b64decode(b64str)
  except Exception as e:
    print("Can't decode base64 ", e)
  s = bitstring.BitArray(bytes).hex
  return "-".join([s[:8],s[8:][:4],s[12:][:4],s[16:][:4],s[20:]])

基於上面的好答案,我編寫了一個不需要 bitstring 包並包含驗證和支持更多輸入選項的版本。

import base64
import regex
import uuid

from typing import Optional


def to_uuid(obj) -> Optional[uuid.UUID]:
    if obj is None:
        return None
    elif isinstance(obj, uuid.UUID):
        return obj
    elif isinstance(obj, str):
        if regex.match(r'[0-9a-fA-F]{8}[-]{0,1}[0-9a-fA-F]{4}[-]{0,1}[0-9a-fA-F]{4}[-]{0,1}[0-9a-fA-F]{4}[-]{0,1}[0-9a-fA-F]{12}', obj):
            return uuid.UUID(hex=obj)
        elif regex.match(r'[0-9a-zA-Z\+\/]{22}[\=]{2}', obj):
            b64_str = base64.b64decode(obj).hex()
            uid_str = '-'.join([b64_str[:8], b64_str[8:][:4], b64_str[12:][:4], b64_str[16:][:4], b64_str[20:]])
            return uuid.UUID(hex=uid_str)
        raise ValueError(f'{obj} is not a valid uuid/guid')
    else:
        raise ValueError(f'{obj} is not a valid uuid/guid')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM