【问题标题】:Convert 64 bit Steam ID to 32 bit account ID将 64 位 Steam ID 转换为 32 位帐户 ID
【发布时间】:2014-04-24 03:26:02
【问题描述】:

如何将 64 位 Steam ID 转换为 32 位帐户 ID? Steam 说要取数字的前 32 位,但你如何在 Node 中做到这一点?

我需要使用 BigNumber 来存储 64 位 int 吗?

【问题讨论】:

  • 是的,您确实需要使用 BigNumber 库。 Javascript numbers 都是 64 位 IEEE 浮点数。注意 Javascript 中的 76561197991791363 === 76561197991791360
  • @YTowOnt9 我刚刚注意到了。为什么最后一个3 特别被选中?这个数字真的太大了吗?
  • 这是关于双精度数的内部表示,类似于0.1 + 0.2 !== 0.3See this question.
  • 数字存储在IEEE 754 64-bit format
  • 你从哪里得到15762817?除非我搞砸了,否则第一组或第二组位都不等于 15762817。

标签: javascript node.js steam


【解决方案1】:

要将 64 位 Steam ID 转换为 32 位帐户 ID,您只需从 64 位 ID 中减去 76561197960265728

这需要节点中的 bigNumber:

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

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,但不想使用 bignumber.js 之类的任何库,因为我的项目非常小,将在网络浏览器中使用。最后我想出了这个优雅的解决方案:

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

    工作原理:

    为了获得较低的 32 位,我们需要将 SteamID64 字符串转换为数字,但由于 JavaScript 的精度限制为 57 位,SteamID64 将被错误地四舍五入。解决方法是截断最左边的数字以获得 16 位数字,该数字最多使用 54 位,因此将在 Javascript 中保持其精度。这是可以接受的,因为最左边的数字来自高 32 位,无论如何都会被清零,因此不会丢失任何有价值的东西。

    为了将剩余的高位归零,我们减去它们所代表的十进制数。如果我们假设我们要转换为public universe 中的每个 SteamID64,这个十进制数将是常数,可以这样计算:

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

    【讨论】:

      【解决方案3】:

      这就是我想出的。我昨天开始学习 JavaScript(来自 C++ 背景,不太习惯在没有类型的情况下工作),所以如果我对语言做了一些愚蠢的事情,请纠正我。我用自己的 Steam ID 对其进行了测试,它似乎可以工作。

      // NOTE: Functions can take in a steamID in its packed 64-bit form 
      // (community 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.com/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 community 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;
      }
      

      【讨论】:

      • node-dota2 有一些我认为的此类功能
      • dev.dota2.com/showthread.php?t=58317 有一些不好的信息,这个答案很完美 - 我已经浪费了大约 5 个小时来尝试各种算法,包括 Valve 文档的位移
      猜你喜欢
      • 1970-01-01
      • 2021-01-22
      • 2014-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      • 1970-01-01
      相关资源
      最近更新 更多