Created
December 24, 2021 09:56
-
-
Save PaulSonOfLars/49039e6422f21d5f54d0fe06e18d5143 to your computer and use it in GitHub Desktop.
Telegram Inline query unhasher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ( | |
"bytes" | |
"encoding/base64" | |
"encoding/binary" | |
"fmt" | |
"strconv" | |
) | |
func UnpackInlineMessageId(inlineMessageId string) (int64, int64, int64, int64, error) { | |
bs, err := base64.RawURLEncoding.DecodeString(inlineMessageId) | |
if err != nil { | |
return 0, 0, 0, 0, fmt.Errorf("failed to base64 decode inline message ID: %w", err) | |
} | |
// unsigned 32 | |
dcId, err := readULong(bs[0:4]) | |
if err != nil { | |
return 0, 0, 0, 0, fmt.Errorf("failed to get DC ID from inline message ID: %w", err) | |
} | |
// unsigned 32 | |
messageId, err := readULong(bs[4:8]) | |
if err != nil { | |
return 0, 0, 0, 0, fmt.Errorf("failed to get message ID from inline message ID: %w", err) | |
} | |
// Some odd logic is required to deal with 32/64 bit ids | |
var chatId int64 | |
var queryId int64 | |
if len(bs) == 20 { | |
// signed 32 | |
chatId, err = readLong(bs[8:12]) | |
if err != nil { | |
return 0, 0, 0, 0, fmt.Errorf("failed to get 32bit chat ID from inline message ID: %w", err) | |
} | |
// signed 64 | |
queryId, err = readLongLong(bs[12:20]) | |
if err != nil { | |
return 0, 0, 0, 0, fmt.Errorf("failed to get query ID from inline message ID: %w", err) | |
} | |
} else { | |
// signed 64 | |
chatId, err = readLongLong(bs[8:16]) | |
if err != nil { | |
return 0, 0, 0, 0, fmt.Errorf("failed to get 64bit chat ID from inline message ID: %w", err) | |
} | |
// signed 64 | |
queryId, err = readLongLong(bs[16:24]) | |
if err != nil { | |
return 0, 0, 0, 0, fmt.Errorf("failed to get query ID from inline message ID: %w", err) | |
} | |
} | |
if chatId < 0 { | |
fullChatId := "-100" + strconv.FormatInt(-chatId, 10) | |
chatId, err = strconv.ParseInt(fullChatId, 10, 64) | |
if err != nil { | |
return 0, 0, 0, 0, fmt.Errorf("failed to fix chat ID to bot API: %w", err) | |
} | |
} | |
return dcId, messageId, chatId, queryId, nil | |
} | |
func readULong(b []byte) (int64, error) { | |
buf := bytes.NewBuffer(b) | |
var x uint32 | |
err := binary.Read(buf, binary.LittleEndian, &x) | |
if err != nil { | |
return 0, err | |
} | |
return int64(x), nil | |
} | |
func readLong(b []byte) (int64, error) { | |
buf := bytes.NewBuffer(b) | |
var x int32 | |
err := binary.Read(buf, binary.LittleEndian, &x) | |
if err != nil { | |
return 0, err | |
} | |
return int64(x), nil | |
} | |
func readLongLong(b []byte) (int64, error) { | |
buf := bytes.NewBuffer(b) | |
var x int64 | |
err := binary.Read(buf, binary.LittleEndian, &x) | |
if err != nil { | |
return 0, err | |
} | |
return x, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment