主頁 > 企業開發 > Delphi:將長十六進制字串轉換為十進制字串

Delphi:將長十六進制字串轉換為十進制字串

2022-11-16 16:06:20 企業開發

我正在使用 Delphi 7 維護一個舊專案。我需要將一個長的十六進制字串轉換為十進制字串。我在 C# 中搜索并找到了示例代碼,但在 Delphi 中找不到。我只有兩個選擇:

  1. 在 Delphi 7 中實作或使用函式。
  2. 在 Delphi 2010 中實作或使用函式,然后將其匯出為 DLL。

我正在處理的十六進制字串的最大長度是 40 個字符,這里是一個示例:


'6F000080B4D4B3426C66A655010001000080B4'

我使用rapidtables進行轉換,這里是輸出

'2475382888117010136950089026926167642744062132'

我希望有人已經解決了這個問題并且可以提供幫助。也許有人給我一個演算法,我可以用它在 Delphi 中撰寫一個函式。

注意:
在 Delphi 7 中,Int64 的最大正值是$7FFFFFFFFFFFFFFF= 9223372036854775807,這個值與我需要的相去甚遠。

uj5u.com熱心網友回復:

為了解決這個問題,我們需要將其分為三個步驟:

  1. 逐位轉換十六進制數。這導致解決如何
  2. 乘以十進制數,這反過來又需要我們能夠
  3. 逐位添加十進制數。

作為其他功能所需的小幫手,讓我擁有這些:

type
  TArrayString= Array of String;  // In case it doesn't exist already

// Fill a text with leading zeroes up to the desired length
procedure MinLen( var s: String; iLen: Integer );
begin
  while Length( s )< iLen do s:= '0'  s;
end;

添加

我們在學校都學過書面加法:將所有數字寫在一行中,然后將每一行的數字相加,并將該和的附加數字帶到被加數的下一行數字中這也可以很容易地完成:

// Addition of multiple long numbers
function Summe( aSummand: TArrayString ): String;
var
  iLenMax, iA, iPos, iSum, iAdvance: Integer;
  c: Char;
begin
  result:= '0';
  case Length( aSummand ) of
    0: exit;  // Nothing to add at all
    1: begin
      result:= aSummand[Low( aSummand )];  // Sum equals the only summand
      exit;
    end;
  end;

  // Find the longest text, then make all texts as long as the longest,
  // so we can simply access an existing character at that position.
  iLenMax:= 0;
  for iA:= Low( aSummand ) to High( aSummand ) do begin
    if Length( aSummand[iA] )> iLenMax then iLenMax:= Length( aSummand[iA] );
  end;
  for iA:= Low( aSummand ) to High( aSummand ) do MinLen( aSummand[iA], iLenMax );
  MinLen( result, iLenMax );

  // All have the same length: process from the least significant digit
  // (right) to the most significant digit (left).
  for iPos:= iLenMax downto 1 do begin
    // Manual addition: write all numbers in one row, then add single
    // digits per row. Nobody will ever give this function so many
    // summands that the sum of single digits will come near the Integer
    // capacity.
    iSum:= 0;
    for iA:= Low( aSummand ) to High( aSummand ) do begin
      Inc( iSum, Ord( aSummand[iA][iPos] )- $30 );  // Add digit from each number
    end;
    Inc( iSum, Ord( result[iPos] )- $30 );  // Also add result's digit from potential previous carry

    // Turn that Integer sum into text again, digit by digit
    iAdvance:= 0;  // Exceeding the current position if we need to carry
    while iSum> 0 do begin
      c:= Chr( (iSum mod 10)  $30 );  // Only the rightmost digit
      if iPos- iAdvance< 1 then begin  // Outside the String?
        result:= c  result;  // Prepend
      end else begin
        result[iPos- iAdvance]:= c;  // Set new digit in overall sum
      end;

      iSum:= iSum div 10;  // This digit has been process, go to next one
      Inc( iAdvance );  // Not in the current position anymore, but processing potential carries
    end;
  end;
end;

由于以下原因,我沒有將它限制為總是 2 個被加數:

  • 處理未知數量的求和數幾乎不需要額外的作業。
  • 一次添加多個加數(而不是總是 2 個)比一次又一次地呼叫此函式更有效。
  • 稍后進行乘法運算時,我們可以用 fe 6 乘以相同的被加數來懶惰地呼叫此函式一次,以模擬乘以 6。

$30是字符的 ASCII 碼'0'- 減去潛在字符'0'to'9'得到'0'0to 9

乘法

我們在學校也都學過書面乘法:對于一個因子的每個數字計算該乘積(只能是 0 到 9 的“簡單”乘法),將所有這些乘積按數字位置連續寫下(可選尾隨零),然后將所有這些產品添加到總和中(參考書面加法)這也可以很容易地完成,因為我們現在已經解決了加法問題:

// Multiplication of two long numbers
function Produkt( s1, s2: String ): String;
var
  iPos, iStep, iA, iNine: Integer;
  aSummand, aStep: TArrayString;
begin
  // For each digit of one factor we will make a separate multiplication
  SetLength( aSummand, Length( s1 ) );

  // This time it doesn't matter how long both numbers are: just again go
  // from least significant digit (right) to most significant digit (left).
  for iPos:= Length( s1 ) downto 1 do begin
    iA:= Length( s1 )- iPos;  // Array index per digit
    // As per our position the sum must be shifted by 10: first (rightmost)
    // digit needs no shift (0), second needs one (10), third needs two (100)...
    MinLen( aSummand[iA], iA );

    // Current digit
    iStep:= Ord( s1[iPos] )- $30;
    case iStep of
      0: ;  // Multiplication by 0 always results in 0, an empty summand equals one of "0"
      1: aSummand[iA]:= s2  aSummand[iA];  // No multiplication needed, just prepend with factor
    else
      // Cheap multiplication: use addition with 2 to 9 times the same summand
      SetLength( aStep, iStep );
      for iNine:= 0 to iStep- 1 do aStep[iNine]:= s2;
      aSummand[iA]:= Summe( aStep )  aSummand[iA];  // Prepend sum, zeroes must be trailing
    end;
  end;

  // Now just add all sums that we got per digit
  result:= Summe( aSummand );
end;

它本來可以更短,因為Summe()已經可以處理 0 和 1 加數——我真的不需要區別對待。如前所述:簡單的乘法是通過簡單的加法完成的——性能效率不高,但易于理解。

十六進制轉十進制

由于我們現在可以進行加法和乘法運算,因此我們還可以轉換非十進制基數的每個數字并將結果增加到總結果:

// Convert base 2..36 long number into base 10 long number
function ConvertToDecimal( sFrom: String; sBase: String= '16' ): String;
var
  sStep, sPos: String;
  cFrom: Char;
  a: TArrayString;
begin
  SetLength( a, 2 );
  a[0]:= '0';  // Overall sum = result
  sPos:= '1';  // Current digit's power
  while Length( sFrom )> 0 do begin  // Process least significant digit (right)
    cFrom:= sFrom[Length( sFrom )];
    case cFrom of  // For now at max base 36 is supported, which includes hexadecimal
      '0'.. '9': sStep:= cFrom;  // Same as text
      'A'.. 'Z': sStep:= IntToStr( Ord( cFrom )- $41  10 );  // Turn "B" into "11"
    end;
    a[1]:= Produkt( sPos, sStep );  // Multiply current digit's value by current position's power
    a[0]:= Summe( a );  // Add both product and current overall result

    sPos:= Produkt( sPos, sBase );  // Increase power to next digit position
    Delete( sFrom, Length( sFrom ), 1 );  // Remove rightmost digit
  end;
  result:= a[0];
end;

它甚至不僅適用于十六進制(以 16 為基數)輸入,還適用于其他輸入。$41是的 ASCII 值'A'- 減去潛在字符'A'to'Z'得到'A'我們的值0to 25,然后我們只需添加10

測驗

字串是隱含的。空格只是出于光學原因。

功能 引數 結果 證明
Summe() 123 456 579
Summe() 123 456 9999 10578 MS calc,大腦
Produkt() 36*12 504 MS calc,大腦
Produkt() 8 6426578999 * 9731421999 8 4105351216 9179999001 rapidtables.com
ConvertToDecimal() 6F0000 80B4D4B3 426C66A6 55010001 000080B4 247538 2888117010 1369500890 2692616764 2744062132 rapidtables.com

概括

  • 這是一個很好的練習,可以將基本/現有技能(算術)轉化為程式代碼,因為需要對邏輯的理解比對編程/語言的理解更多,因此它對初學者(仍在為編程苦苦掙扎)和專家(主要專注于關于任務自動化)。
  • 就性能而言,這肯定遠非最佳,但應該很容易理解/理解/遵循而不是難以閱讀。同樣,它應該很容易翻譯成其他語言。
  • 額外的練習是還可以添加減法和除法。
  • 一些微小的細節被省略,fe 數字總是被期望沒有前導零 - 結果可能也有不需要的前導零。空字串被解釋為0,但 的結果0也不會減少為空字串。
  • 它適用于任何 String 型別,因為無論如何我們只對 ASCII 進行操作 - 無需區分AnsiString,UnicodeString等等WideString但是,Char用作系結到該選擇的型別。但是功能Chr()Ord()應該再次支持一切。

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/534520.html

標籤:德尔福德尔福-2010飞利浦

上一篇:如何使用onDrawColumnCell更改單元格文本而不在Delphi上使用textout?

下一篇:TMemoryStream到位元組陣列

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more