通過同態加密實現可編程隱私和鏈上合規

1. 引言

2023年9月28日,a16z 的加密團隊發布了 Nakamoto Challenge,列出了區塊鏈中需要解決的最重要問題。尤其是其中的第四個問題格外引人注意:“合規的可編程隱私”,因為Zama團隊已經在這方面積極思考了一段時間。本文提出了使用同態加密和Zama fhEVM 機密智能合約協議的第一個解決方案。

fhEVM 是一個常規的 EVM,它通過一些預編譯功能使得使用Zama TFHE-rs 同態加密庫可以對加密狀態進行計算。從開發者的角度來看,這里沒有涉及加密學:

  • 他們只需編寫使用所提供的加密數據類型(如 euint32、ebool 等)的 Solidity 代碼。

與其他隱私解決方案相比,fhEVM 的一個大優勢是所有數據和計算都發生在鏈上。這意味著可以像常規的明文合約一樣,擁有相同的組合性和數據可用性。【本文各種接口已被重構,理解思想即可。】

這一特性是構建可編程隱私的關鍵,因為所有的訪問控制邏輯都可以在合約本身中定義。協議中沒有任何需要硬編碼的部分,用戶也不需要進行鏈下操作來確保合規性。應用可以直接強化執行合規性,僅用幾行 Solidity 代碼!

本文將展示如何使用鏈上 DID 構建一個合規的 ERC20 代幣。

2. 通過鏈上機密 DID 實現身份抽象

去中心化標識符(Decentralized Identifier,DID)是一種由實體(如政府、登記機關、公司或用戶本人)頒發的獨特數字身份。DID 可以與一個加密密鑰相關聯,用于證明用戶擁有該 DID,如 EVM 錢包。但它也可以存儲一整套屬性,如用戶的年齡、國籍、社會安全號碼等。這些屬性可以用來證明你滿足某些條件(稱為“證明”),如超過18歲或不是納尼亞國公民。

大多數 DID 實現是在客戶端進行的,并使用零知識證明生成證明。雖然在許多情況下這已經足夠,但當涉及多個用戶參與交易、需要對 DID 應用復雜規則或需要為所有人維護一套共同的規則時,這個方案會變得復雜起來。這實際上是邊緣計算與云計算應用之間的取舍問題。

然而,擁有一個集中式的 DID 注冊中心可以解決這些問題,因為可以簡單地請求注冊中心來檢查每個人是否符合要求。它還可以簡化監管的追蹤,因為只需要在一個地方實現它。區塊鏈將是一個完美的基礎設施,因為它可以實現 DID 與需要合規性的應用之間的組合性,以及不同法規之間的組合性。

問題是:每個人都能看到每個人的身份!

幸運的是,有一個解決方案:

  • 同態加密,具體來說是 fhEVM!
    • 得益于對加密狀態的組合性能力,可以直接將用戶的 DID 以加密形式托管在鏈上,并讓合規應用通過簡單的合約調用來驗證屬性。
    • 通過智能合約管理身份的能力,稱之為“身份抽象”,這類似于如何通過智能合約管理資金的賬戶抽象。

這個教程分為三部分:

  • 1)身份抽象:是通過一個注冊合約來完成的,注冊合約負責管理身份和證明。在這里,假設 DID 是官方政府身份證明。注冊中心由一個中央機構(如 AFNIC)管理,后者可以創建注冊商(如 KYC 公司,如 Onfido、Jumio 等),然后這些注冊商可以創建用戶 DID。用戶通過他們的注冊商來管理和更新他們的 DID。
  • 2)監管:在一個合約中定義,該合約編碼了一套基于用戶 DID 中信息的規則,用于管理個人之間的代幣轉移。它基本上在合約級別強制執行監管,而不是在用戶級別。
  • 3)合規的機密轉賬:在一個合規的 ERC20 合約中實現,該合約使用監管合約來執行代幣轉移中的合規性,而不需要對 ERC20 API 本身進行任何更改。在這個示例中,使用了一個機密 ERC20 合約,其中余額和金額是隱藏的,但它同樣適用于常規的明文 ERC20 代幣。

Zama鏈上機密 DID 協議架構:
在這里插入圖片描述

3. 身份注冊合約

IdentityRegistry 合約是一個用戶 DID 的注冊中心,這些 DID 是由注冊商頒發的,并包含一組加密的標識符,如用戶的國籍、年齡、社會安全號碼等。這些標識符作為加密的 32 位值(euint32)存儲。

該合約還處理權限管理,如下所示:

  • 允許合約所有者(如 AFNIC)添加、移除或更新注冊商。
  • 允許注冊商添加、移除或更新他們創建的用戶 DID。
  • 允許用戶授權智能合約訪問他們 DID 的特定屬性。需要注意的是,用戶有責任不向惡意合約提供訪問權限,就像他們有責任不讓惡意合約花費他們的代幣一樣。

第一步,實現創建和管理 DID 的邏輯:

// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity 0.8.19;import "fhevm/lib/TFHE.sol";contract IdentityRegistry is EIP712WithModifier, Ownable {// 從錢包到注冊商ID的映射mapping(address => uint) public registrars;// 從錢包到身份的映射mapping(address => Identity) internal identities;struct Identity {uint registrarId;mapping(string => euint32) identifiers;}mapping(address => mapping(address => mapping(string => bool))) permissions; // 用戶 => 合約 => 標識符[]event NewRegistrar(address wallet, uint registrarId);event NewDid(address wallet);event RemoveDid(address wallet);constructor() Ownable() EIP712WithModifier("Authorization token", "1") {_transferOwnership(msg.sender);}// 添加注冊商function addRegistrar(address wallet, uint registrarId) public onlyOwner {require(registrarId > 0, "registrarId needs to be > 0");registrars[wallet] = registrarId;emit NewRegistrar(wallet, registrarId);}function removeRegistrar(address wallet) public onlyOwner {delete registrars[wallet];}function getRegistrar(address wallet) public view returns (uint) {return identities[wallet].registrarId;}// 添加用戶 DIDfunction addDid(address wallet) public onlyRegistrar {require(identities[wallet].registrarId == 0, "This wallet is already registered");Identity storage newIdentity = identities[wallet];newIdentity.registrarId = registrars[msg.sender];emit NewDid(wallet);}function removeDid(address wallet) public onlyExistingWallet(wallet) onlyRegistrarOf(wallet) {require(identities[wallet].registrarId > 0, "This wallet isn't registered");delete identities[wallet];emit RemoveDid(wallet);}modifier onlyExistingWallet(address wallet) {require(identities[wallet].registrarId > 0, "This wallet isn't registered");_;}modifier onlyRegistrar() {require(registrars[msg.sender] > 0, "You're not a registrar");_;}modifier onlyRegistrarOf(address wallet) {uint registrarId = registrars[msg.sender];require(identities[wallet].registrarId == registrarId, "You're not managing this identity");_;}
}

其中:

  • onlyRegistraronlyRegistrarOf 注冊商(Registrar):只有注冊商可以添加或刪除用戶的 DID。每個錢包都與一個注冊商 ID 相關聯,注冊商 ID 必須大于 0。
  • 身份管理:每個用戶都有一個關聯的 Identity,其中包含該用戶的注冊商 ID 和一組加密的標識符(如年齡、國籍等)。
  • 權限管理:用戶可以授權特定的智能合約訪問其 DID 的特定屬性。合約會驗證這些權限,確保只有經過授權的合約可以訪問用戶的身份信息。
  • 合約功能:
    • addRegistrar:允許合約所有者添加新的注冊商。
    • removeRegistrar:允許合約所有者移除注冊商。
    • addDid:允許注冊商為錢包添加 DID。
    • removeDid:允許注冊商移除錢包的 DID。
    • getRegistrar:查詢用戶 DID 所屬的注冊商 ID。

通過這種方式,可以在鏈上安全地管理和更新用戶的身份信息,同時保證隱私性和合規性。

現在,下一步是實現identifiers標識符和訪問控制的邏輯。

標識符只是一個字符串(如“出生日期”)和一個加密的 32 位值。它只能由注冊商創建或更新,用戶不能創建自己的標識符,因為希望這些標識符由注冊商進行認證。

然而,由于標識符是加密的,用戶需要授權某個合約訪問特定的值,將通過一個簡單的訪問控制機制來處理這一點,這類似于你如何允許合約花費你的 ERC20 代幣。

contract IdentityRegistry is EIP712WithModifier, Ownable {...mapping(address => mapping(address => mapping(string => bool))) permissions; // 用戶 => 合約 => 標識符[]// 設置用戶的標識符function setIdentifier(address wallet, string calldata identifier, bytes calldata encryptedValue) public {euint32 value = TFHE.asEuint32(encryptedValue);setIdentifier(wallet, identifier, value);}function setIdentifier(address wallet,string calldata identifier,euint32 value) internal onlyExistingWallet(wallet) onlyRegistrarOf(wallet) {identities[wallet].identifiers[identifier] = value;}// 用戶處理權限function grantAccess(address allowed, string[] calldata identifiers) public {for (uint i = 0; i < identifiers.length; i++) {permissions[msg.sender][allowed][identifiers[i]] = true;}}function revokeAccess(address allowed, string[] calldata identifiers) public {for (uint i = 0; i < identifiers.length; i++) {delete permissions[msg.sender][allowed][identifiers[i]];}}...
}

現在可以通過添加必要的 getter 來完成身份注冊合約,同時加入一些條件和錯誤處理。

contract IdentityRegistry is EIP712WithModifier, Ownable {...// 獲取加密的標識符function reencryptIdentifier(address wallet,string calldata identifier,bytes32 publicKey,bytes calldata signature) public view onlySignedPublicKey(publicKey, signature) returns (bytes memory) {euint32 ident = _getIdentifier(wallet, identifier);require(TFHE.isInitialized(ident), "This identifier is unknown");return TFHE.reencrypt(ident, publicKey, 0);}function getIdentifier(address wallet, string calldata identifier) public view returns (euint32) {return _getIdentifier(wallet, identifier);}function _getIdentifier(address wallet,string calldata identifier) internal view onlyExistingWallet(wallet) onlyAllowed(wallet, identifier) returns (euint32) {return identities[wallet].identifiers[identifier];}modifier onlyAllowed(address wallet, string memory identifier) {require(owner() == msg.sender || permissions[wallet][msg.sender][identifier],"User didn't give you permission to access this identifier.");_;}
}

其中:

  • setIdentifier:允許注冊商為錢包設置新的標識符。標識符是通過加密的 32 位值進行存儲。
  • grantAccessrevokeAccess:允許用戶授權或撤銷合約訪問其標識符的權限,權限是基于合約和標識符的。
  • reencryptIdentifier:允許用戶通過簽名證明他們的身份,并獲取加密的標識符。這是為了確保數據的安全傳輸和使用。
  • getIdentifier_getIdentifier:獲取標識符的加密值,只有授權的合約和用戶才能訪問。
  • onlyAllowed:訪問控制修飾符,確保只有授權的用戶和合約可以訪問特定的標識符。

通過這樣的設計,可以確保用戶的身份信息在鏈上安全存儲,同時保證合規性和隱私保護。

4. 規則合約

下一步是創建規則合約。

在為兩個個體之間的轉賬實現一組規則時,需要認識到這些規則可能會隨著時間的推移而變化。擁有一個單一的智能合約來定義給定上下文(如貨幣轉賬)的所有規則,意味著 ERC20 合約不必自己跟蹤規則。政府可以簡單地更新這個合約,并且它會自動傳播到所有實現了該合約的代幣。

從本質上講,規則合約只是一組與加密的身份屬性匹配的條件。為了避免濫用,用戶不會直接授予規則合約訪問權限,而是將權限授予 ERC20 代幣合約,然后它執行一個委托調用到規則合約。這樣做確保了只有用戶信任的 ERC20 合約才能訪問他們的信息。請記住,在進行轉賬之前,發送方和接收方都必須授予 ERC20 合約訪問權限。

在本例中將實現一些基本規則:

  • 在同一國家內的轉賬沒有限制,但轉賬到其他國家的金額限制為 10,000 個代幣。
  • 被列入黑名單的用戶不能進行轉賬或接收代幣。
  • 用戶不能將代幣轉賬到被列入黑名單的國家。

與其讓交易失敗(這可能會暴露敏感信息),將簡單地將轉賬金額設置為 0,如果沒有滿足其中一個條件。這使用了一個同態三元操作符,稱為 cmuxvalue = TFHE.cmux(encryptedCondition, valueIfTrue, valueIfFalse);

// SPDX-License-Identifier: BSD-3-Clause-Clearpragma solidity 0.8.19;import "fhevm/lib/TFHE.sol";
import "./IdentityRegistry.sol";interface ICompliantERC20 {function getIdentifier(address wallet, string calldata identifier) external view returns (euint32);
}contract ERC20Rules {string[] public identifiers;mapping(address => uint32) public whitelistedWallets;mapping(string => uint8) public countries;uint16[] public country2CountryRestrictions;constructor() {identifiers = ["country", "blacklist"];whitelistedWallets[address(0x133725C6461120439E85887C7639316CB27a2D9d)] = 1;whitelistedWallets[address(0x4CaCeF78615AFecEf7eF182CfbD243195Fc90a29)] = 2;countries["fr"] = 1;countries["us"] = 2;country2CountryRestrictions = [createRestriction(countries["us"], countries["fr"])];}function createRestriction(uint16 from, uint16 to) internal pure returns (uint16) {return (from << 8) + to;}function getIdentifiers() public view returns (string[] memory) {return identifiers;}function getC2CRestrictions() public view returns (uint16[] memory) {return country2CountryRestrictions;}function transfer(address from, address to, euint32 amount) public view returns (euint32) {ICompliantERC20 erc20 = ICompliantERC20(msg.sender);// 條件 1:不同國家之間的轉賬限額為 10,000 個代幣ebool transferLimitOK = checkLimitTransfer(erc20, from, to, amount);ebool condition = transferLimitOK;// 條件 2:檢查是否有黑名單用戶ebool blacklistOK = checkBlacklist(erc20, from, to);condition = TFHE.and(condition, blacklistOK);// 條件 3:檢查國家間轉賬規則ebool c2cOK = checkCountryToCountry(erc20, from, to);condition = TFHE.and(condition, c2cOK);return TFHE.cmux(condition, amount, TFHE.asEuint32(0));}function checkLimitTransfer(ICompliantERC20 erc20,address from,address to,euint32 amount) internal view returns (ebool) {euint8 fromCountry = TFHE.asEuint8(erc20.getIdentifier(from, "country"));euint8 toCountry = TFHE.asEuint8(erc20.getIdentifier(to, "country"));require(TFHE.isInitialized(fromCountry) && TFHE.isInitialized(toCountry), "You don't have access");ebool sameCountry = TFHE.eq(fromCountry, toCountry);ebool amountBelow10k = TFHE.le(amount, 10000);return TFHE.or(sameCountry, amountBelow10k);}function checkBlacklist(ICompliantERC20 erc20, address from, address to) internal view returns (ebool) {ebool fromBlacklisted = TFHE.asEbool(erc20.getIdentifier(from, "blacklist"));ebool toBlacklisted = TFHE.asEbool(erc20.getIdentifier(to, "blacklist"));return TFHE.not(TFHE.and(toBlacklisted, fromBlacklisted));}function checkCountryToCountry(ICompliantERC20 erc20, address from, address to) internal view returns (ebool) {// 禁止從國家 2 轉賬到國家 1uint16[] memory c2cRestrictions = getC2CRestrictions();euint32 fromCountry = erc20.getIdentifier(from, "country");euint32 toCountry = erc20.getIdentifier(to, "country");require(TFHE.isInitialized(fromCountry) && TFHE.isInitialized(toCountry), "You don't have access");euint16 countryToCountry = TFHE.shl(TFHE.asEuint16(fromCountry), 8) + TFHE.asEuint16(toCountry);ebool condition = TFHE.asEbool(true);// 檢查所有國家間的轉賬限制for (uint i = 0; i < c2cRestrictions.length; i++) {condition = TFHE.and(condition, TFHE.ne(countryToCountry, c2cRestrictions[i]));}return condition;}
}

其中:

  • createRestriction:創建一個國家到國家的轉賬限制,兩個國家通過一個 16 位的編碼表示。
  • getIdentifiers:返回所有的標識符數組。
  • getC2CRestrictions:返回所有的國家間轉賬限制。
  • transfer:檢查轉賬是否滿足所有條件(如限額、黑名單、國家間轉賬規則),如果任何條件不滿足,則將轉賬金額設置為 0。
  • checkLimitTransfer:檢查轉賬是否超出了不同國家之間的限額。
  • checkBlacklist:檢查發送方和接收方是否在黑名單中。
  • checkCountryToCountry:檢查兩個國家之間是否允許轉賬。

這種設計可以確保在轉賬過程中遵循規則和合規性要求,同時保障用戶的隱私和安全。

5. 合規的機密 ERC20 合約

現在有了身份注冊合約和規則合約,接下來創建合規、隱私保護的代幣合約。這個合約將被稱為 CompliantERC20,并具有以下關鍵特性:

  • 用戶余額和轉賬金額是加密的。
  • 轉賬時通過調用規則合約來強制執行合規性。
  • 某些余額的可見性可以授予白名單地址(如監管機構)。
// SPDX-License-Identifier: BSD-3-Clause-Clearpragma solidity 0.8.19;import "fhevm/abstracts/EIP712WithModifier.sol";
import "./ERC20Rules.sol";
import "./IdentityRegistry.sol";abstract contract AbstractCompliantERC20 is EIP712WithModifier {IdentityRegistry identityContract;ERC20Rules rulesContract;mapping(address => euint32) internal balances;constructor(address _identityAddr, address _rulesAddr) EIP712WithModifier("Authorization token", "1") {identityContract = IdentityRegistry(_identityAddr);rulesContract = ERC20Rules(_rulesAddr);}function identifiers() public view returns (string[] memory) {return rulesContract.getIdentifiers();}function getIdentifier(address wallet, string calldata identifier) external view returns (euint32) {require(msg.sender == address(rulesContract), "Access restricted to the current ERC20Rules");return identityContract.getIdentifier(wallet, identifier);}function balanceOf(address wallet,bytes32 publicKey,bytes calldata signature) public view onlySignedPublicKey(publicKey, signature) returns (bytes memory) {// 用戶可以查看自己的余額if (wallet == msg.sender) {return TFHE.reencrypt(balances[msg.sender], publicKey, 0);}// 國家可以查看所有公民的余額uint32 userCountry = rulesContract.whitelistedWallets(msg.sender);require(userCountry > 0, "You're not registered as a whitelisted wallet");euint32 walletCountry = identityContract.getIdentifier(wallet, "country");ebool sameCountry = TFHE.eq(walletCountry, userCountry);euint32 balance = TFHE.isInitialized(balances[wallet]) ? balances[wallet] : TFHE.asEuint32(0);balance = TFHE.cmux(sameCountry, balance, TFHE.asEuint32(0));return TFHE.reencrypt(balance, publicKey, 0);}// 轉賬加密金額function _transfer(address from, address to, euint32 _amount) internal {// 條件 1:資金充足ebool enoughFund = TFHE.le(_amount, balances[from]);euint32 amount = TFHE.cmux(enoughFund, _amount, TFHE.asEuint32(0));amount = rulesContract.transfer(from, to, amount);balances[to] = balances[to] + amount;balances[from] = balances[from] - amount;}
}

其中:

  • balanceOf:此方法根據用戶的公鑰和簽名返回加密后的余額。用戶只能查看自己的余額,如果是同一國家的用戶,國家可以查看所有公民的余額。
  • _transfer:在轉賬過程中,通過規則合約來強制執行合規性,確保資金充足后,轉賬金額經過合規性檢查,然后將金額從發送方轉賬到接收方。

在這個合約中,規則合約是通過簡單的調用來觸發的。這意味著用戶必須在發起任何轉賬之前提供對 ERC20 合約的訪問權限;否則,轉賬將被回滾。

最終,創建的 ERC20 合約:

// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity 0.8.19;import "fhevm/lib/TFHE.sol";
import "./AbstractCompliantERC20.sol";contract CompliantERC20 is AbstractCompliantERC20 {...// 從消息發送者地址轉賬加密金額到 `to` 地址function transfer(address to, bytes calldata encryptedAmount) public {transfer(to, TFHE.asEuint32(encryptedAmount));}// 從消息發送者地址轉賬金額到 `to` 地址function transfer(address to, euint32 amount) public {_transfer(msg.sender, to, amount);}
}

與用戶授權 DeFi 協議花費他們的代幣類似,用戶需要授權合約訪問規則合約所需的標識符。這是通過調用 Identity.grantAccess(contractAddress, identifiers) 來實現的,標識符可以通過調用 ERC20.identifiers() view方法來獲取。這個列表直接來自 ERC20Rules 合約,用于允許屬性的更新。

6. 合規性與隱私可以共存!

如果擁有正確的工具,構建合規性并不是一件困難的事情。雖然Zama最初構建了 fhEVM 以在區塊鏈中實現隱私保護,但很快意識到,這項技術可以用于身份管理,從而實現可編程的合規性。

參考資料

[1] Zama團隊2023年11月23日博客 Programmable Privacy and Onchain Compliance using Homomorphic Encryption

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/914354.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/914354.shtml
英文地址,請注明出處:http://en.pswp.cn/news/914354.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

封裝---統一封裝處理頁面標題

一.采用工具來實現(setPageTitle.ts)多個頁面中用更統一的方式設置 document.title&#xff0c;可以封裝一個工具函數:在utils目錄下新建文件:setPageTitle.ts如果要在每個頁面設置相同的網站標志可以使用下面的appNameconst appName: string import.meta.env.VITE_APP_NAMEex…

JAVA學習筆記 首個HelloWorld程序-002

目錄 1 前言 2 開發首個程序 3 小結 1 前言 在所有的開發語言中&#xff0c;基本上首先程序就是輸出HelloWorld&#xff0c;這里也不例外。這個需要注意的是&#xff0c;程序的核心功能是數據輸出&#xff0c;是要有一個結果&#xff0c;可能沒有輸入&#xff0c;但是一定有…

智慧監所:科技賦能監獄管理新變革

1. 高清教育&#xff1a;告別模糊畫面&#xff0c;學習更清晰傳統電視的雪花屏終于成為歷史&#xff01;新系統采用高清傳輸&#xff0c;課件文字清晰可見&#xff0c;教學視頻細節分明。某監獄教育科王警官說&#xff1a;"現在播放法律課程&#xff0c;服刑人員能清楚看到…

專題:2025供應鏈數智化與效率提升報告|附100+份報告PDF、原數據表匯總下載

全文鏈接&#xff1a;https://tecdat.cn/?p42926 在全球產業鏈重構與數字技術革命的雙重驅動下&#xff0c;供應鏈正經歷從傳統經驗驅動向數據智能驅動的范式變革。從快消品產能區域化布局到垂類折扣企業的效率競賽&#xff0c;從人形機器人的成本優化到供應鏈金融對中小企業的…

uniapp+vue3+ts項目:實現小程序文件下載、預覽、進度監聽(含項目、案例、插件)

uniapp+vue3+ts項目:實現小程序文件下載、預覽、進度監聽(含項目、案例、插件) 支持封裝調用: 項目采用uniapp+vue3+ts +京東nutUI 開發nutUi文檔:loadingPage組件:https://uniapp-nutui.tech/components/exhibition/loadingpage.html案例效果圖: 略博主自留地:參考本地…

用Python和OpenCV從零搭建一個完整的雙目視覺系統(六 最終篇)

本系列文章旨在系統性地闡述如何利用 Python 與 OpenCV 庫&#xff0c;從零開始構建一個完整的雙目立體視覺系統。 本項目github地址&#xff1a;https://github.com/present-cjn/stereo-vision-python.git 1. 概述 歡迎來到本系列文章的最后一篇。在過去的幾篇文章中&#…

Android View 繪制流程 簡述 (無限遞歸+BitMap問題)

繪制流程 在 Android 的 View 系統中&#xff0c;draw(canvas) 和 dispatchDraw(canvas) 是繪制流程中的兩個關鍵方法&#xff1a; 1. draw(canvas) 方法的作用 draw(canvas) 是 View 類中的核心繪制方法&#xff0c;它的主要職責包括&#xff1a; 繪制背景 - 調用 drawBac…

算法學習筆記:18.拉斯維加斯算法 ——從原理到實戰,涵蓋 LeetCode 與考研 408 例題

在隨機化算法領域&#xff0c;拉斯維加斯&#xff08;Las Vegas&#xff09;算法以其獨特的設計思想占據重要地位。與蒙特卡洛&#xff08;Monte Carlo&#xff09;算法不同&#xff0c;拉斯維加斯算法總能給出正確的結果&#xff0c;但運行時間具有隨機性 —— 在最壞情況下可…

26-計組-指令執行過程

一、指令周期1. 定義與組成定義&#xff1a;CPU取出并執行一條指令所需的全部時間&#xff0c;稱為指令周期。子周期劃分&#xff1a;取指周期&#xff08;必選&#xff09;&#xff1a;從存儲器取指令到指令寄存器&#xff08;IR&#xff09;。間址周期&#xff08;可選&#…

【JMeter】數據驅動測試

文章目錄創建數據文件加載數據文件根據數據文件請求接口、傳遞參數拓展含義&#xff1a;根據數據的數量、內容&#xff0c;自動的決定用例的數據和內容。數據驅動測試用例。步驟&#xff1a; 創建數據文件加載數據文件根據數據文件請求接口、傳遞參數 創建數據文件 Jmeter支…

Springboot實現一個接口加密

首先來看效果這個主要是為了防止篡改請求的。 我們這里采用的是一個AOP的攔截&#xff0c;在有需要這樣的接口上添加了加密處理。 下面是一些功能防篡改HMAC-SHA256 參數簽名密鑰僅客戶端 & 服務器持有防重放秒級時間戳 有效窗口校驗默認允許 5 分鐘防竊聽AES/CBC/PKCS5Pa…

斯坦福 CS336 動手大語言模型 Assignment1 BPE Tokenizer TransformerLM

所有代碼更新至 https://github.com/WangYuHang-cmd/CS336/tree/main/assignment1-basics 作業文件結構: CS336/assignment1-basics/ ├── tests/ # 測試文件目錄 │ ├── adapters.py # 適配器測試 │ ├── conftest.py # pyt…

Spring Cloud Gateway 實戰指南

關鍵詞&#xff1a;微服務、API網關、Spring Cloud Gateway、路由轉發、限流熔斷 ? 文章摘要 隨著互聯網應用規模的不斷擴大&#xff0c;傳統的單體架構逐漸向微服務架構轉型。在微服務架構中&#xff0c;API 網關作為系統的入口點&#xff0c;承擔了諸如請求路由、負載均衡、…

PyTorch自動微分:從基礎到實戰

目錄 1. 自動微分是什么&#xff1f; 1.1 計算圖 1.2 requires_grad 屬性 2. 標量和向量的梯度計算 2.1 標量梯度 2.2 向量梯度 3. 梯度上下文控制 3.1 禁用梯度計算 3.2 累計梯度 4. 梯度下降實戰 4.1 求函數最小值 4.2 線性回歸參數求解 5. 總結 在深度學習中&a…

Spring AI 項目實戰(十六):Spring Boot + AI + 通義萬相圖像生成工具全棧項目實戰(附完整源碼)

系列文章 序號文章名稱1Spring AI 項目實戰(一):Spring AI 核心模塊入門2Spring AI 項目實戰(二):Spring Boot + AI + DeepSeek 深度實戰(附完整源碼)3Spring AI 項目實戰(三):Spring Boot + AI + DeepSeek 打造智能客服系統(附完整源碼)4

從零到一:企業如何組建安全團隊

在這個"黑客滿天飛&#xff0c;漏洞遍地跑"的時代&#xff0c;沒有安全團隊的企業就像裸奔的勇士——雖然很有勇氣&#xff0c;但結局往往很悲慘。 &#x1f4cb; 目錄 為什么要組建安全團隊安全團隊的核心職能團隊架構設計人員配置策略技術體系建設制度流程建立實施…

業務訪問控制-ACL與包過濾

業務訪問控制-ACL與包過濾 ACL的定義及應用場景ACL&#xff08;Access Control List&#xff0c;訪問控制列表&#xff09;是用來實現數據包識別功能的&#xff1b;ACL可以應用于諸多場景&#xff1a; 包過濾功能&#xff1a;對數據包進行放通或過濾操作。NAT&#xff08;Netwo…

穿梭時空的智慧向導:Deepoc具身智能如何賦予導覽機器人“人情味”

穿梭時空的智慧向導&#xff1a;Deepoc具身智能如何賦予導覽機器人“人情味”清晨&#xff0c;當第一縷陽光透過高大的彩繪玻璃窗&#xff0c;灑在博物館光潔的地板上&#xff0c;一位特別的“館員”已悄然“蘇醒”。它沒有制服&#xff0c;卻有著清晰的指引&#xff1b;它無需…

PostgreSQL 查詢庫中所有表占用磁盤大小、表大小

SELECTn.nspname AS schema_name,c.relname AS table_name,-- 1?? 總大小&#xff08;表 toast 索引&#xff09;pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size,-- 2?? 表不包含索引&#xff08;含 TOAST&#xff09;pg_size_pretty(pg_total_relation_s…

日記-生活隨想

最近鼠鼠也是來到上海打拼&#xff08;實習&#xff09;了&#xff0c;那么秉持著來都來了的原則&#xff0c;鼠鼠也是去bw逛了逛&#xff0c;雖說沒票只能在外場看看&#x1f62d;。可惜幾乎沒有多少我非常喜歡的ip&#xff0c;不由感慨現在的二次元圈已經變樣了。雖說我知道內…