te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Convert 64 bit Steam ID to 32 bit account ID - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Convert 64 bit Steam ID to 32 bit account ID - Stack Overflow

programmeradmin3浏览0评论

How do I convert a 64 bit steam ID to a 32 bit account ID? Steam says to take the first 32 bits of the number, but how do you do this in Node?

Do I need to use BigNumber to store the 64 bit int?

How do I convert a 64 bit steam ID to a 32 bit account ID? Steam says to take the first 32 bits of the number, but how do you do this in Node?

Do I need to use BigNumber to store the 64 bit int?

Share Improve this question edited Apr 24, 2014 at 4:37 Christian Stewart asked Apr 24, 2014 at 3:26 Christian StewartChristian Stewart 15.5k21 gold badges84 silver badges144 bronze badges 6
  • 2 Yes, you do need to use a BigNumber library. Javascript numbers are all 64-bit IEEE floating point numbers. Notive that 76561197991791363 === 76561197991791360 in Javascript. – Paul Commented Apr 24, 2014 at 3:34
  • @YTowOnt9 I just noticed that. Why is the last 3 in particular picked off? Is the number really one digit too large? – Christian Stewart Commented Apr 24, 2014 at 3:38
  • It's about the internal representation of doubles, similar to how 0.1 + 0.2 !== 0.3. See this question. – Paul Commented Apr 24, 2014 at 3:40
  • Numbers are stored in the IEEE 754 64-bit format – Paul Commented Apr 24, 2014 at 3:40
  • 1 Where do you get 15762817 from? Unless I've screwed something up, neither the first or the second set of bits are equal to 15762817. – Qantas 94 Heavy Commented Apr 24, 2014 at 3:50
 |  Show 1 more ment

4 Answers 4

Reset to default 8

To convert a 64 bit Steam ID to a 32 bit Account ID, you can just subtract 76561197960265728 from the 64 bit id.

This requires bigNumber in node:

bignumber = require("bignumber.js");
console.log(bignumber('76561197991791363').minus('76561197960265728'))

I had the same issue but didn't want to use any library like bignumber.js as my project was quite small and will be used in a web browser. In the end I came up with this elegant solution:

function steamID64toSteamID32 (steamID64) {
    return Number(steamID64.substr(-16,16)) - 6561197960265728
}

How it works:

To get the lower 32 bits we need to convert the SteamID64 string to a number, but because JavaScript has a precision limit of 57 bits the SteamID64 will be erroneously rounded. The workaround is to truncate the leftmost digits to get a 16 digit number, which uses at most 54 bits and will therefore retain its precision in Javascript. This is acceptable because the leftmost digits es from the higher 32 bits which will be zeroed anyway, so nothing of value will be lost.

To zero the remaining higher bits we subtract the decimal number they're representing. If we assume that every SteamID64 we're converting to be in the public universe this decimal number will be constant and can be puted like this:

1. 0b00000001000100000000000000000001 0b00000000000000000000000000000000 = 76561197960265728
2. Number('76561197960265728'.substr(-16,16)) = 6561197960265728

Here's what I came up with. I started learning JavaScript yesterday (ing from a C++ background, not very accustomed to working without types), so correct me if I did something derpy with the language. I tested it with my own steam ID and it seems to work.

// NOTE: Functions can take in a steamID in its packed 64-bit form 
// (munity ID starting with 765), its modern form with or without 
// either or both brackets, and its legacy form. SteamID's that 
// contain letters (e.g. STEAM_0... or [U:1...) are not case-sensitive.

// Dependencies: BigInteger library, available from http://silentmatt./biginteger/

// Global variable used by all conversion functions
var STEAM_BASELINE = '76561197960265728';

// IN: String containing a steamID in any of the 3 formats
// OUT: String containing the steamID as a munity ID (64-bit packed ID)
function ConvertToPacked(inputID)
{
    var output = "unknown";

    // From packed
    if(inputID.match(/^765/) && inputID.length > 15)
    {
        output = inputID;
    }

    // From modern
    else if(inputID.match(/^\[U:1:/i) || inputID.match(/^U:1:/i))
    {
        var numericPortion = inputID.replace(/^\[U:1:|^U:1:/i,'').replace(/\]/,'');
        output = BigInteger.add(numericPortion, STEAM_BASELINE).toString();
    }

    // From legacy
    else if(inputID.match(/^STEAM_0:[0-1]:/i))
    {
        var splitID = inputID.split(":");
        var product = BigInteger.multiply(splitID[2],2);
        var sum = BigInteger.add(product, STEAM_BASELINE);
        output = BigInteger.add(sum, splitID[1]).toString();
    }

    return output;
}

// IN: String containing a steamID in any of the 3 formats
// OUT: String containing the steamID in the modern format (e.g. [U:1:123456])
function ConvertToModern(inputID)
{
    var output = "unknown";

    // From packed
    if(inputID.match(/^765/) && inputID.length > 15)
    {
        output = "[U:1:" + BigInteger.subtract(inputID, STEAM_BASELINE).toString() + "]";
    }

    // From modern
    else if(inputID.match(/^\[U:1:/i) || inputID.match(/^U:1:/i))
    {
        var numericPortion = inputID.replace(/^\[U:1:|^U:1:/i,'').replace(/\]/,'');
        output = "[U:1:" + numericPortion + "]";
    }

    // From legacy
    else if(inputID.match(/^STEAM_0:[0-1]:/i))
    {
        var splitID = inputID.split(":");
        var numeric = BigInteger.add(BigInteger.multiply(splitID[2],2), splitID[1]);
        output = "[U:1:" + numeric.toString() + "]";        
    }

    return output;
}

// IN: String containing a steamID in any of the 3 formats
// OUT: String containing the steamID in the legacy format (e.g. STEAM_0:0:123456)
function ConvertToLegacy(inputID)
{
    var output = "unknown"

    // From packed
    if(inputID.match(/^765/) && inputID.length > 15)
    {        
        var z = BigInteger.divide(BigInteger.subtract(inputID, STEAM_BASELINE), 2);
        var y = BigInteger.remainder(inputID, 2);
        output = 'STEAM_0:' + y.toString() + ':' + z.toString();
    }
    // From modern
    else if(inputID.match(/^\[U:1:/i) || inputID.match(/^U:1:/i))
    {
        var numericPortion = inputID.replace(/^\[U:1:|^U:1:/i,'').replace(/\]/,'');
        var z = BigInteger.divide(numericPortion, 2);
        var y = BigInteger.remainder(numericPortion, 2);
        output = 'STEAM_0:' + y.toString() + ':' + z.toString();
    }
    // From legacy
    else if(inputID.match(/^STEAM_0:[0-1]:/i))
    {
        output = inputID.toUpperCase();
    }

    return output;
}

Nodejs now supports BigInt as of Node version ~10. Additionally, MDN shows that BigInt is widely available in the browser.

This allows for simple subtraction:

// Note: Pass your number as a string to the BigInt constructor
// Number to subtract from your 64-bit SteamID
const steamBaseline = BigInt("76561197960265728");
// Your 64-bit SteamID
const steamId64 = BigInt("76561197991791363");
// Result
const steamId32 = (steamId64 - steamBaseline).toString();
发布评论

评论列表(0)

  1. 暂无评论