Repalce QuicheTextUtils::HexEncode/Decode with Abseil equivalents.

PiperOrigin-RevId: 339366305
Change-Id: Ifa155b75569a17f3f3be908c7d0a9f9de7b9474c
diff --git a/common/platform/api/quiche_text_utils.h b/common/platform/api/quiche_text_utils.h
index 5bc5f50..1a11c2a 100644
--- a/common/platform/api/quiche_text_utils.h
+++ b/common/platform/api/quiche_text_utils.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "absl/types/optional.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_export.h"
@@ -32,32 +33,12 @@
     return quiche::QuicheTextUtilsImpl::Uint64ToString(in);
   }
 
-  // This converts |length| bytes of binary to a 2*|length|-character
-  // hexadecimal representation.
-  // Return value: 2*|length| characters of ASCII string.
-  static std::string HexEncode(const char* data, size_t length) {
-    return HexEncode(absl::string_view(data, length));
-  }
-
-  // This converts |data.length()| bytes of binary to a
-  // 2*|data.length()|-character hexadecimal representation.
-  // Return value: 2*|data.length()| characters of ASCII string.
-  static std::string HexEncode(absl::string_view data) {
-    return quiche::QuicheTextUtilsImpl::HexEncode(data);
-  }
-
   // This converts a uint32 into an 8-character hexidecimal
   // representation.  Return value: 8 characters of ASCII string.
   static std::string Hex(uint32_t v) {
     return quiche::QuicheTextUtilsImpl::Hex(v);
   }
 
-  // Converts |data| from a hexadecimal ASCII string to a binary string
-  // that is |data.length()/2| bytes long.
-  static std::string HexDecode(absl::string_view data) {
-    return quiche::QuicheTextUtilsImpl::HexDecode(data);
-  }
-
   // Base64 encodes with no padding |data_len| bytes of |data| into |output|.
   static void Base64Encode(const uint8_t* data,
                            size_t data_len,
diff --git a/common/platform/api/quiche_text_utils_test.cc b/common/platform/api/quiche_text_utils_test.cc
index 012d33d..f85f8b0 100644
--- a/common/platform/api/quiche_text_utils_test.cc
+++ b/common/platform/api/quiche_text_utils_test.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_test.h"
 
 namespace quiche {
@@ -37,21 +38,6 @@
   EXPECT_EQ("1234", quiche::QuicheTextUtils::Uint64ToString(1234));
 }
 
-TEST_F(QuicheTextUtilsTest, HexEncode) {
-  EXPECT_EQ("48656c6c6f", quiche::QuicheTextUtils::HexEncode("Hello", 5));
-  EXPECT_EQ("48656c6c6f", quiche::QuicheTextUtils::HexEncode("Hello World", 5));
-  EXPECT_EQ("48656c6c6f", quiche::QuicheTextUtils::HexEncode("Hello"));
-  EXPECT_EQ("0102779cfa",
-            quiche::QuicheTextUtils::HexEncode("\x01\x02\x77\x9c\xfa"));
-}
-
-TEST_F(QuicheTextUtilsTest, HexDecode) {
-  EXPECT_EQ("Hello", quiche::QuicheTextUtils::HexDecode("48656c6c6f"));
-  EXPECT_EQ("", quiche::QuicheTextUtils::HexDecode(""));
-  EXPECT_EQ("\x01\x02\x77\x9c\xfa",
-            quiche::QuicheTextUtils::HexDecode("0102779cfa"));
-}
-
 TEST_F(QuicheTextUtilsTest, HexDump) {
   // Verify output of the HexDump method is as expected.
   char packet[] = {
@@ -72,14 +58,13 @@
       "0x0040:  6c69 6e65 7320 6f66 206f 7574 7075 742e  lines.of.output.\n"
       "0x0050:  0102 03                                  ...\n");
   // Verify that 0x21 and 0x7e are printable, 0x20 and 0x7f are not.
-  EXPECT_EQ("0x0000:  2021 7e7f                                .!~.\n",
-            quiche::QuicheTextUtils::HexDump(
-                quiche::QuicheTextUtils::HexDecode("20217e7f")));
+  EXPECT_EQ(
+      "0x0000:  2021 7e7f                                .!~.\n",
+      quiche::QuicheTextUtils::HexDump(absl::HexStringToBytes("20217e7f")));
   // Verify that values above numeric_limits<unsigned char>::max() are formatted
   // properly on platforms where char is unsigned.
   EXPECT_EQ("0x0000:  90aa ff                                  ...\n",
-            quiche::QuicheTextUtils::HexDump(
-                quiche::QuicheTextUtils::HexDecode("90aaff")));
+            quiche::QuicheTextUtils::HexDump(absl::HexStringToBytes("90aaff")));
 }
 
 TEST_F(QuicheTextUtilsTest, Base64Encode) {
diff --git a/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc b/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
index 5b25250..aba1001 100644
--- a/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
+++ b/quic/core/crypto/aes_128_gcm_12_decrypter_test.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -234,14 +235,14 @@
       bool has_pt = test_vectors[j].pt;
 
       // Decode the test vector.
-      std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key);
-      std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv);
-      std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct);
-      std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad);
-      std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag);
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
       std::string pt;
       if (has_pt) {
-        pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt);
+        pt = absl::HexStringToBytes(test_vectors[j].pt);
       }
 
       // The test vector's lengths should look sane. Note that the lengths
diff --git a/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc b/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
index 1216f95..1495fd0 100644
--- a/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
+++ b/quic/core/crypto/aes_128_gcm_12_encrypter_test.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -183,12 +184,12 @@
     const TestGroupInfo& test_info = test_group_info[i];
     for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
       // Decode the test vector.
-      std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key);
-      std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv);
-      std::string pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt);
-      std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad);
-      std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct);
-      std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag);
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
 
       // The test vector's lengths should look sane. Note that the lengths
       // in |test_info| are in bits.
diff --git a/quic/core/crypto/aes_128_gcm_decrypter_test.cc b/quic/core/crypto/aes_128_gcm_decrypter_test.cc
index 7625f7a..d4f38b9 100644
--- a/quic/core/crypto/aes_128_gcm_decrypter_test.cc
+++ b/quic/core/crypto/aes_128_gcm_decrypter_test.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
@@ -228,14 +229,14 @@
       bool has_pt = test_vectors[j].pt;
 
       // Decode the test vector.
-      std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key);
-      std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv);
-      std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct);
-      std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad);
-      std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag);
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
       std::string pt;
       if (has_pt) {
-        pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt);
+        pt = absl::HexStringToBytes(test_vectors[j].pt);
       }
 
       // The test vector's lengths should look sane. Note that the lengths
@@ -274,15 +275,14 @@
 
 TEST_F(Aes128GcmDecrypterTest, GenerateHeaderProtectionMask) {
   Aes128GcmDecrypter decrypter;
-  std::string key =
-      quiche::QuicheTextUtils::HexDecode("d9132370cb18476ab833649cf080d970");
+  std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970");
   std::string sample =
-      quiche::QuicheTextUtils::HexDecode("d1d7998068517adb769b48b924a32c47");
+      absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47");
   QuicDataReader sample_reader(sample.data(), sample.size());
   ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
   std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
   std::string expected_mask =
-      quiche::QuicheTextUtils::HexDecode("b132c37d6164da4ea4dc9b763aceec27");
+      absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27");
   quiche::test::CompareCharArraysWithHexError(
       "header protection mask", mask.data(), mask.size(), expected_mask.data(),
       expected_mask.size());
diff --git a/quic/core/crypto/aes_128_gcm_encrypter_test.cc b/quic/core/crypto/aes_128_gcm_encrypter_test.cc
index 462c2e4..c7c096f 100644
--- a/quic/core/crypto/aes_128_gcm_encrypter_test.cc
+++ b/quic/core/crypto/aes_128_gcm_encrypter_test.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
@@ -182,12 +183,12 @@
     const TestGroupInfo& test_info = test_group_info[i];
     for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
       // Decode the test vector.
-      std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key);
-      std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv);
-      std::string pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt);
-      std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad);
-      std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct);
-      std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag);
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
 
       // The test vector's lengths should look sane. Note that the lengths
       // in |test_info| are in bits.
@@ -219,16 +220,13 @@
 }
 
 TEST_F(Aes128GcmEncrypterTest, EncryptPacket) {
-  std::string key =
-      quiche::QuicheTextUtils::HexDecode("d95a145250826c25a77b6a84fd4d34fc");
-  std::string iv =
-      quiche::QuicheTextUtils::HexDecode("50c4431ebb18283448e276e2");
+  std::string key = absl::HexStringToBytes("d95a145250826c25a77b6a84fd4d34fc");
+  std::string iv = absl::HexStringToBytes("50c4431ebb18283448e276e2");
   uint64_t packet_num = 0x13278f44;
   std::string aad =
-      quiche::QuicheTextUtils::HexDecode("875d49f64a70c9cbe713278f44ff000005");
-  std::string pt =
-      quiche::QuicheTextUtils::HexDecode("aa0003a250bd000000000001");
-  std::string ct = quiche::QuicheTextUtils::HexDecode(
+      absl::HexStringToBytes("875d49f64a70c9cbe713278f44ff000005");
+  std::string pt = absl::HexStringToBytes("aa0003a250bd000000000001");
+  std::string ct = absl::HexStringToBytes(
       "7dd4708b989ee7d38a013e3656e9b37beefd05808fe1ab41e3b4f2c0");
 
   std::vector<char> out(ct.size());
@@ -260,14 +258,13 @@
 
 TEST_F(Aes128GcmEncrypterTest, GenerateHeaderProtectionMask) {
   Aes128GcmEncrypter encrypter;
-  std::string key =
-      quiche::QuicheTextUtils::HexDecode("d9132370cb18476ab833649cf080d970");
+  std::string key = absl::HexStringToBytes("d9132370cb18476ab833649cf080d970");
   std::string sample =
-      quiche::QuicheTextUtils::HexDecode("d1d7998068517adb769b48b924a32c47");
+      absl::HexStringToBytes("d1d7998068517adb769b48b924a32c47");
   ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
   std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
   std::string expected_mask =
-      quiche::QuicheTextUtils::HexDecode("b132c37d6164da4ea4dc9b763aceec27");
+      absl::HexStringToBytes("b132c37d6164da4ea4dc9b763aceec27");
   quiche::test::CompareCharArraysWithHexError(
       "header protection mask", mask.data(), mask.size(), expected_mask.data(),
       expected_mask.size());
diff --git a/quic/core/crypto/aes_256_gcm_decrypter_test.cc b/quic/core/crypto/aes_256_gcm_decrypter_test.cc
index ef7bb95..c688ce4 100644
--- a/quic/core/crypto/aes_256_gcm_decrypter_test.cc
+++ b/quic/core/crypto/aes_256_gcm_decrypter_test.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -233,14 +234,14 @@
       bool has_pt = test_vectors[j].pt;
 
       // Decode the test vector.
-      std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key);
-      std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv);
-      std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct);
-      std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad);
-      std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag);
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
       std::string pt;
       if (has_pt) {
-        pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt);
+        pt = absl::HexStringToBytes(test_vectors[j].pt);
       }
 
       // The test vector's lengths should look sane. Note that the lengths
@@ -279,15 +280,15 @@
 
 TEST_F(Aes256GcmDecrypterTest, GenerateHeaderProtectionMask) {
   Aes256GcmDecrypter decrypter;
-  std::string key = quiche::QuicheTextUtils::HexDecode(
+  std::string key = absl::HexStringToBytes(
       "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788");
   std::string sample =
-      quiche::QuicheTextUtils::HexDecode("4d190c474be2b8babafb49ec4e38e810");
+      absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810");
   QuicDataReader sample_reader(sample.data(), sample.size());
   ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
   std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
   std::string expected_mask =
-      quiche::QuicheTextUtils::HexDecode("db9ed4e6ccd033af2eae01407199c56e");
+      absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e");
   quiche::test::CompareCharArraysWithHexError(
       "header protection mask", mask.data(), mask.size(), expected_mask.data(),
       expected_mask.size());
diff --git a/quic/core/crypto/aes_256_gcm_encrypter_test.cc b/quic/core/crypto/aes_256_gcm_encrypter_test.cc
index c6bb294..c09f8a8 100644
--- a/quic/core/crypto/aes_256_gcm_encrypter_test.cc
+++ b/quic/core/crypto/aes_256_gcm_encrypter_test.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -190,12 +191,12 @@
     const TestGroupInfo& test_info = test_group_info[i];
     for (size_t j = 0; test_vectors[j].key != nullptr; j++) {
       // Decode the test vector.
-      std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[j].key);
-      std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[j].iv);
-      std::string pt = quiche::QuicheTextUtils::HexDecode(test_vectors[j].pt);
-      std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[j].aad);
-      std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[j].ct);
-      std::string tag = quiche::QuicheTextUtils::HexDecode(test_vectors[j].tag);
+      std::string key = absl::HexStringToBytes(test_vectors[j].key);
+      std::string iv = absl::HexStringToBytes(test_vectors[j].iv);
+      std::string pt = absl::HexStringToBytes(test_vectors[j].pt);
+      std::string aad = absl::HexStringToBytes(test_vectors[j].aad);
+      std::string ct = absl::HexStringToBytes(test_vectors[j].ct);
+      std::string tag = absl::HexStringToBytes(test_vectors[j].tag);
 
       // The test vector's lengths should look sane. Note that the lengths
       // in |test_info| are in bits.
@@ -242,14 +243,14 @@
 
 TEST_F(Aes256GcmEncrypterTest, GenerateHeaderProtectionMask) {
   Aes256GcmEncrypter encrypter;
-  std::string key = quiche::QuicheTextUtils::HexDecode(
+  std::string key = absl::HexStringToBytes(
       "ed23ecbf54d426def5c52c3dcfc84434e62e57781d3125bb21ed91b7d3e07788");
   std::string sample =
-      quiche::QuicheTextUtils::HexDecode("4d190c474be2b8babafb49ec4e38e810");
+      absl::HexStringToBytes("4d190c474be2b8babafb49ec4e38e810");
   ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
   std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
   std::string expected_mask =
-      quiche::QuicheTextUtils::HexDecode("db9ed4e6ccd033af2eae01407199c56e");
+      absl::HexStringToBytes("db9ed4e6ccd033af2eae01407199c56e");
   quiche::test::CompareCharArraysWithHexError(
       "header protection mask", mask.data(), mask.size(), expected_mask.data(),
       expected_mask.size());
diff --git a/quic/core/crypto/cert_compressor_test.cc b/quic/core/crypto/cert_compressor_test.cc
index 6a3c27c..87446ac 100644
--- a/quic/core/crypto/cert_compressor_test.cc
+++ b/quic/core/crypto/cert_compressor_test.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <string>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -22,7 +23,7 @@
   std::vector<std::string> chain;
   const std::string compressed = CertCompressor::CompressChain(
       chain, absl::string_view(), absl::string_view(), nullptr);
-  EXPECT_EQ("00", quiche::QuicheTextUtils::HexEncode(compressed));
+  EXPECT_EQ("00", absl::BytesToHexString(compressed));
 
   std::vector<std::string> chain2, cached_certs;
   ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs, nullptr,
@@ -36,8 +37,7 @@
   const std::string compressed = CertCompressor::CompressChain(
       chain, absl::string_view(), absl::string_view(), nullptr);
   ASSERT_GE(compressed.size(), 2u);
-  EXPECT_EQ("0100",
-            quiche::QuicheTextUtils::HexEncode(compressed.substr(0, 2)));
+  EXPECT_EQ("0100", absl::BytesToHexString(compressed.substr(0, 2)));
 
   std::vector<std::string> chain2, cached_certs;
   ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs, nullptr,
@@ -62,7 +62,7 @@
       "2a00000000000000" /* set hash 42 */
       "01000000"         /* index 1 */
       "00" /* end of list */,
-      quiche::QuicheTextUtils::HexEncode(compressed));
+      absl::BytesToHexString(compressed));
 
   std::vector<std::string> chain2, cached_certs;
   ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs,
@@ -79,9 +79,9 @@
   const std::string compressed = CertCompressor::CompressChain(
       chain, absl::string_view(), hash_bytes, nullptr);
 
-  EXPECT_EQ("02" /* cached */ + quiche::QuicheTextUtils::HexEncode(hash_bytes) +
+  EXPECT_EQ("02" /* cached */ + absl::BytesToHexString(hash_bytes) +
                 "00" /* end of list */,
-            quiche::QuicheTextUtils::HexEncode(compressed));
+            absl::BytesToHexString(compressed));
 
   std::vector<std::string> cached_certs, chain2;
   cached_certs.push_back(chain[0]);
@@ -95,37 +95,37 @@
   std::vector<std::string> cached_certs, chain;
 
   EXPECT_FALSE(CertCompressor::DecompressChain(
-      quiche::QuicheTextUtils::HexEncode("04") /* bad entry type */,
-      cached_certs, nullptr, &chain));
+      absl::BytesToHexString("04") /* bad entry type */, cached_certs, nullptr,
+      &chain));
 
   EXPECT_FALSE(CertCompressor::DecompressChain(
-      quiche::QuicheTextUtils::HexEncode("01") /* no terminator */,
-      cached_certs, nullptr, &chain));
+      absl::BytesToHexString("01") /* no terminator */, cached_certs, nullptr,
+      &chain));
 
   EXPECT_FALSE(CertCompressor::DecompressChain(
-      quiche::QuicheTextUtils::HexEncode("0200") /* hash truncated */,
-      cached_certs, nullptr, &chain));
+      absl::BytesToHexString("0200") /* hash truncated */, cached_certs,
+      nullptr, &chain));
 
   EXPECT_FALSE(CertCompressor::DecompressChain(
-      quiche::QuicheTextUtils::HexEncode("0300") /* hash and index truncated */,
+      absl::BytesToHexString("0300") /* hash and index truncated */,
       cached_certs, nullptr, &chain));
 
   /* without a CommonCertSets */
-  EXPECT_FALSE(CertCompressor::DecompressChain(
-      quiche::QuicheTextUtils::HexEncode("03"
-                                         "0000000000000000"
-                                         "00000000"),
-      cached_certs, nullptr, &chain));
+  EXPECT_FALSE(
+      CertCompressor::DecompressChain(absl::BytesToHexString("03"
+                                                             "0000000000000000"
+                                                             "00000000"),
+                                      cached_certs, nullptr, &chain));
 
   std::unique_ptr<CommonCertSets> common_sets(
       crypto_test_utils::MockCommonCertSets("foo", 42, 1));
 
   /* incorrect hash and index */
-  EXPECT_FALSE(CertCompressor::DecompressChain(
-      quiche::QuicheTextUtils::HexEncode("03"
-                                         "a200000000000000"
-                                         "00000000"),
-      cached_certs, nullptr, &chain));
+  EXPECT_FALSE(
+      CertCompressor::DecompressChain(absl::BytesToHexString("03"
+                                                             "a200000000000000"
+                                                             "00000000"),
+                                      cached_certs, nullptr, &chain));
 }
 
 }  // namespace test
diff --git a/quic/core/crypto/chacha20_poly1305_decrypter_test.cc b/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
index ab1baad..3711104 100644
--- a/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
+++ b/quic/core/crypto/chacha20_poly1305_decrypter_test.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <string>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -143,15 +144,14 @@
     bool has_pt = test_vectors[i].pt;
 
     // Decode the test vector.
-    std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[i].key);
-    std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[i].iv);
-    std::string fixed =
-        quiche::QuicheTextUtils::HexDecode(test_vectors[i].fixed);
-    std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[i].aad);
-    std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[i].ct);
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
     std::string pt;
     if (has_pt) {
-      pt = quiche::QuicheTextUtils::HexDecode(test_vectors[i].pt);
+      pt = absl::HexStringToBytes(test_vectors[i].pt);
     }
 
     ChaCha20Poly1305Decrypter decrypter;
diff --git a/quic/core/crypto/chacha20_poly1305_encrypter_test.cc b/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
index ec6b887..91b32ef 100644
--- a/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
+++ b/quic/core/crypto/chacha20_poly1305_encrypter_test.cc
@@ -92,7 +92,7 @@
   ChaCha20Poly1305Encrypter encrypter;
   ChaCha20Poly1305Decrypter decrypter;
 
-  std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[0].key);
+  std::string key = absl::HexStringToBytes(test_vectors[0].key);
   ASSERT_TRUE(encrypter.SetKey(key));
   ASSERT_TRUE(decrypter.SetKey(key));
   ASSERT_TRUE(encrypter.SetNoncePrefix("abcd"));
@@ -116,13 +116,12 @@
 TEST_F(ChaCha20Poly1305EncrypterTest, Encrypt) {
   for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
     // Decode the test vector.
-    std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[i].key);
-    std::string pt = quiche::QuicheTextUtils::HexDecode(test_vectors[i].pt);
-    std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[i].iv);
-    std::string fixed =
-        quiche::QuicheTextUtils::HexDecode(test_vectors[i].fixed);
-    std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[i].aad);
-    std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[i].ct);
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string pt = absl::HexStringToBytes(test_vectors[i].pt);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
 
     ChaCha20Poly1305Encrypter encrypter;
     ASSERT_TRUE(encrypter.SetKey(key));
diff --git a/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc b/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
index 2c7aba1..431f012 100644
--- a/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
+++ b/quic/core/crypto/chacha20_poly1305_tls_decrypter_test.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <string>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -138,15 +139,14 @@
     bool has_pt = test_vectors[i].pt;
 
     // Decode the test vector.
-    std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[i].key);
-    std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[i].iv);
-    std::string fixed =
-        quiche::QuicheTextUtils::HexDecode(test_vectors[i].fixed);
-    std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[i].aad);
-    std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[i].ct);
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
     std::string pt;
     if (has_pt) {
-      pt = quiche::QuicheTextUtils::HexDecode(test_vectors[i].pt);
+      pt = absl::HexStringToBytes(test_vectors[i].pt);
     }
 
     ChaCha20Poly1305TlsDecrypter decrypter;
@@ -172,14 +172,14 @@
 
 TEST_F(ChaCha20Poly1305TlsDecrypterTest, GenerateHeaderProtectionMask) {
   ChaCha20Poly1305TlsDecrypter decrypter;
-  std::string key = quiche::QuicheTextUtils::HexDecode(
+  std::string key = absl::HexStringToBytes(
       "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7");
   std::string sample =
-      quiche::QuicheTextUtils::HexDecode("1210d91cceb45c716b023f492c29e612");
+      absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612");
   QuicDataReader sample_reader(sample.data(), sample.size());
   ASSERT_TRUE(decrypter.SetHeaderProtectionKey(key));
   std::string mask = decrypter.GenerateHeaderProtectionMask(&sample_reader);
-  std::string expected_mask = quiche::QuicheTextUtils::HexDecode("1cc2cd98dc");
+  std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc");
   quiche::test::CompareCharArraysWithHexError(
       "header protection mask", mask.data(), mask.size(), expected_mask.data(),
       expected_mask.size());
diff --git a/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc b/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
index 276a413..1918d2a 100644
--- a/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
+++ b/quic/core/crypto/chacha20_poly1305_tls_encrypter_test.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/crypto/chacha20_poly1305_tls_decrypter.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
@@ -92,7 +93,7 @@
   ChaCha20Poly1305TlsEncrypter encrypter;
   ChaCha20Poly1305TlsDecrypter decrypter;
 
-  std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[0].key);
+  std::string key = absl::HexStringToBytes(test_vectors[0].key);
   ASSERT_TRUE(encrypter.SetKey(key));
   ASSERT_TRUE(decrypter.SetKey(key));
   ASSERT_TRUE(encrypter.SetIV("abcdefghijkl"));
@@ -116,13 +117,12 @@
 TEST_F(ChaCha20Poly1305TlsEncrypterTest, Encrypt) {
   for (size_t i = 0; test_vectors[i].key != nullptr; i++) {
     // Decode the test vector.
-    std::string key = quiche::QuicheTextUtils::HexDecode(test_vectors[i].key);
-    std::string pt = quiche::QuicheTextUtils::HexDecode(test_vectors[i].pt);
-    std::string iv = quiche::QuicheTextUtils::HexDecode(test_vectors[i].iv);
-    std::string fixed =
-        quiche::QuicheTextUtils::HexDecode(test_vectors[i].fixed);
-    std::string aad = quiche::QuicheTextUtils::HexDecode(test_vectors[i].aad);
-    std::string ct = quiche::QuicheTextUtils::HexDecode(test_vectors[i].ct);
+    std::string key = absl::HexStringToBytes(test_vectors[i].key);
+    std::string pt = absl::HexStringToBytes(test_vectors[i].pt);
+    std::string iv = absl::HexStringToBytes(test_vectors[i].iv);
+    std::string fixed = absl::HexStringToBytes(test_vectors[i].fixed);
+    std::string aad = absl::HexStringToBytes(test_vectors[i].aad);
+    std::string ct = absl::HexStringToBytes(test_vectors[i].ct);
 
     ChaCha20Poly1305TlsEncrypter encrypter;
     ASSERT_TRUE(encrypter.SetKey(key));
@@ -158,13 +158,13 @@
 
 TEST_F(ChaCha20Poly1305TlsEncrypterTest, GenerateHeaderProtectionMask) {
   ChaCha20Poly1305TlsEncrypter encrypter;
-  std::string key = quiche::QuicheTextUtils::HexDecode(
+  std::string key = absl::HexStringToBytes(
       "6a067f432787bd6034dd3f08f07fc9703a27e58c70e2d88d948b7f6489923cc7");
   std::string sample =
-      quiche::QuicheTextUtils::HexDecode("1210d91cceb45c716b023f492c29e612");
+      absl::HexStringToBytes("1210d91cceb45c716b023f492c29e612");
   ASSERT_TRUE(encrypter.SetHeaderProtectionKey(key));
   std::string mask = encrypter.GenerateHeaderProtectionMask(sample);
-  std::string expected_mask = quiche::QuicheTextUtils::HexDecode("1cc2cd98dc");
+  std::string expected_mask = absl::HexStringToBytes("1cc2cd98dc");
   quiche::test::CompareCharArraysWithHexError(
       "header protection mask", mask.data(), mask.size(), expected_mask.data(),
       expected_mask.size());
diff --git a/quic/core/crypto/crypto_handshake_message.cc b/quic/core/crypto/crypto_handshake_message.cc
index 1b61da3..75bd3fe 100644
--- a/quic/core/crypto/crypto_handshake_message.cc
+++ b/quic/core/crypto/crypto_handshake_message.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <string>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h"
 #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
@@ -370,7 +371,7 @@
     if (!done) {
       // If there's no specific format for this tag, or the value is invalid,
       // then just use hex.
-      ret += "0x" + quiche::QuicheTextUtils::HexEncode(it->second);
+      ret += "0x" + absl::BytesToHexString(it->second);
     }
     ret += "\n";
   }
diff --git a/quic/core/crypto/crypto_message_printer_bin.cc b/quic/core/crypto/crypto_message_printer_bin.cc
index f5584ad..9a4e223 100644
--- a/quic/core/crypto/crypto_message_printer_bin.cc
+++ b/quic/core/crypto/crypto_message_printer_bin.cc
@@ -10,6 +10,7 @@
 #include <iostream>
 #include <string>
 
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
@@ -47,7 +48,7 @@
   quic::CryptoFramer framer;
   framer.set_visitor(&printer);
   framer.set_process_truncated_messages(true);
-  std::string input = quiche::QuicheTextUtils::HexDecode(messages[0]);
+  std::string input = absl::HexStringToBytes(messages[0]);
   if (!framer.ProcessInput(input)) {
     return 1;
   }
diff --git a/quic/core/crypto/crypto_server_test.cc b/quic/core/crypto/crypto_server_test.cc
index c68fcc2..51dc418 100644
--- a/quic/core/crypto/crypto_server_test.cc
+++ b/quic/core/crypto/crypto_server_test.cc
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "third_party/boringssl/src/include/openssl/sha.h"
 #include "net/third_party/quiche/src/quic/core/crypto/cert_compressor.h"
@@ -135,9 +136,9 @@
     char public_value[32];
     memset(public_value, 42, sizeof(public_value));
 
-    nonce_hex_ = "#" + quiche::QuicheTextUtils::HexEncode(GenerateNonce());
-    pub_hex_ = "#" + quiche::QuicheTextUtils::HexEncode(public_value,
-                                                        sizeof(public_value));
+    nonce_hex_ = "#" + absl::BytesToHexString(GenerateNonce());
+    pub_hex_ = "#" + absl::BytesToHexString(
+                         absl::string_view(public_value, sizeof(public_value)));
 
     CryptoHandshakeMessage client_hello =
         crypto_test_utils::CreateCHLO({{"PDMD", "X509"},
@@ -158,7 +159,7 @@
 
     absl::string_view srct;
     ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
-    srct_hex_ = "#" + quiche::QuicheTextUtils::HexEncode(srct);
+    srct_hex_ = "#" + absl::BytesToHexString(srct);
 
     absl::string_view scfg;
     ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg));
@@ -166,7 +167,7 @@
 
     absl::string_view scid;
     ASSERT_TRUE(server_config_->GetStringPiece(kSCID, &scid));
-    scid_hex_ = "#" + quiche::QuicheTextUtils::HexEncode(scid);
+    scid_hex_ = "#" + absl::BytesToHexString(scid);
 
     signed_config_ = QuicReferenceCountedPointer<QuicSignedServerConfig>(
         new QuicSignedServerConfig());
@@ -340,8 +341,8 @@
 
   std::string XlctHexString() {
     uint64_t xlct = crypto_test_utils::LeafCertHashForTesting();
-    return "#" + quiche::QuicheTextUtils::HexEncode(
-                     reinterpret_cast<char*>(&xlct), sizeof(xlct));
+    return "#" + absl::BytesToHexString(absl::string_view(
+                     reinterpret_cast<char*>(&xlct), sizeof(xlct)));
   }
 
  protected:
diff --git a/quic/core/crypto/crypto_utils_test.cc b/quic/core/crypto/crypto_utils_test.cc
index 1c67cc8..e0d1165 100644
--- a/quic/core/crypto/crypto_utils_test.cc
+++ b/quic/core/crypto/crypto_utils_test.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
@@ -53,16 +54,14 @@
   for (size_t i = 0; i < ABSL_ARRAYSIZE(test_vector); i++) {
     // Decode the test vector.
     std::string subkey_secret =
-        quiche::QuicheTextUtils::HexDecode(test_vector[i].subkey_secret);
-    std::string label =
-        quiche::QuicheTextUtils::HexDecode(test_vector[i].label);
-    std::string context =
-        quiche::QuicheTextUtils::HexDecode(test_vector[i].context);
+        absl::HexStringToBytes(test_vector[i].subkey_secret);
+    std::string label = absl::HexStringToBytes(test_vector[i].label);
+    std::string context = absl::HexStringToBytes(test_vector[i].context);
     size_t result_len = test_vector[i].result_len;
     bool expect_ok = test_vector[i].expected != nullptr;
     std::string expected;
     if (expect_ok) {
-      expected = quiche::QuicheTextUtils::HexDecode(test_vector[i].expected);
+      expected = absl::HexStringToBytes(test_vector[i].expected);
     }
 
     std::string result;
diff --git a/quic/core/crypto/quic_crypto_server_config.cc b/quic/core/crypto/quic_crypto_server_config.cc
index 42379ad..5169f9b 100644
--- a/quic/core/crypto/quic_crypto_server_config.cc
+++ b/quic/core/crypto/quic_crypto_server_config.cc
@@ -11,6 +11,7 @@
 #include <utility>
 
 #include "absl/base/attributes.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "third_party/boringssl/src/include/openssl/sha.h"
 #include "third_party/boringssl/src/include/openssl/ssl.h"
@@ -408,7 +409,7 @@
     if (configs_.find(config->id) != configs_.end()) {
       QUIC_LOG(WARNING) << "Failed to add config because another with the same "
                            "server config id already exists: "
-                        << quiche::QuicheTextUtils::HexEncode(config->id);
+                        << absl::BytesToHexString(config->id);
       return nullptr;
     }
 
@@ -454,7 +455,7 @@
       return false;
     }
     QUIC_LOG(INFO) << "Fallback config has scid "
-                   << quiche::QuicheTextUtils::HexEncode(fallback_config->id);
+                   << absl::BytesToHexString(fallback_config->id);
     parsed_configs.push_back(fallback_config);
   } else {
     QUIC_LOG(INFO) << "No fallback config provided";
@@ -474,26 +475,27 @@
   for (const QuicReferenceCountedPointer<Config>& config : parsed_configs) {
     auto it = configs_.find(config->id);
     if (it != configs_.end()) {
-      QUIC_LOG(INFO)
-          << "Keeping scid: " << quiche::QuicheTextUtils::HexEncode(config->id)
-          << " orbit: "
-          << quiche::QuicheTextUtils::HexEncode(
-                 reinterpret_cast<const char*>(config->orbit), kOrbitSize)
-          << " new primary_time " << config->primary_time.ToUNIXSeconds()
-          << " old primary_time " << it->second->primary_time.ToUNIXSeconds()
-          << " new priority " << config->priority << " old priority "
-          << it->second->priority;
+      QUIC_LOG(INFO) << "Keeping scid: " << absl::BytesToHexString(config->id)
+                     << " orbit: "
+                     << absl::BytesToHexString(absl::string_view(
+                            reinterpret_cast<const char*>(config->orbit),
+                            kOrbitSize))
+                     << " new primary_time "
+                     << config->primary_time.ToUNIXSeconds()
+                     << " old primary_time "
+                     << it->second->primary_time.ToUNIXSeconds()
+                     << " new priority " << config->priority << " old priority "
+                     << it->second->priority;
       // Update primary_time and priority.
       it->second->primary_time = config->primary_time;
       it->second->priority = config->priority;
       new_configs.insert(*it);
     } else {
-      QUIC_LOG(INFO) << "Adding scid: "
-                     << quiche::QuicheTextUtils::HexEncode(config->id)
+      QUIC_LOG(INFO) << "Adding scid: " << absl::BytesToHexString(config->id)
                      << " orbit: "
-                     << quiche::QuicheTextUtils::HexEncode(
+                     << absl::BytesToHexString(absl::string_view(
                             reinterpret_cast<const char*>(config->orbit),
-                            kOrbitSize)
+                            kOrbitSize))
                      << " primary_time " << config->primary_time.ToUNIXSeconds()
                      << " priority " << config->priority;
       new_configs.emplace(config->id, config);
@@ -1172,10 +1174,10 @@
     primary_config_ = new_primary;
     new_primary->is_primary = true;
     QUIC_DLOG(INFO) << "New primary config.  orbit: "
-                    << quiche::QuicheTextUtils::HexEncode(
-                           reinterpret_cast<const char*>(
-                               primary_config_->orbit),
-                           kOrbitSize);
+                    << absl::BytesToHexString(
+                           absl::string_view(reinterpret_cast<const char*>(
+                                                 primary_config_->orbit),
+                                             kOrbitSize));
     if (primary_config_changed_cb_ != nullptr) {
       primary_config_changed_cb_->Run(primary_config_->id);
     }
@@ -1192,11 +1194,10 @@
   primary_config_ = new_primary;
   new_primary->is_primary = true;
   QUIC_DLOG(INFO) << "New primary config.  orbit: "
-                  << quiche::QuicheTextUtils::HexEncode(
+                  << absl::BytesToHexString(absl::string_view(
                          reinterpret_cast<const char*>(primary_config_->orbit),
-                         kOrbitSize)
-                  << " scid: "
-                  << quiche::QuicheTextUtils::HexEncode(primary_config_->id);
+                         kOrbitSize))
+                  << " scid: " << absl::BytesToHexString(primary_config_->id);
   next_config_promotion_time_ = QuicWallTime::Zero();
   if (primary_config_changed_cb_ != nullptr) {
     primary_config_changed_cb_->Run(primary_config_->id);
diff --git a/quic/core/crypto/quic_hkdf_test.cc b/quic/core/crypto/quic_hkdf_test.cc
index bee3540..48e089f 100644
--- a/quic/core/crypto/quic_hkdf_test.cc
+++ b/quic/core/crypto/quic_hkdf_test.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
 
@@ -71,11 +72,10 @@
     const HKDFInput& test(kHKDFInputs[i]);
     SCOPED_TRACE(i);
 
-    const std::string key = quiche::QuicheTextUtils::HexDecode(test.key_hex);
-    const std::string salt = quiche::QuicheTextUtils::HexDecode(test.salt_hex);
-    const std::string info = quiche::QuicheTextUtils::HexDecode(test.info_hex);
-    const std::string expected =
-        quiche::QuicheTextUtils::HexDecode(test.output_hex);
+    const std::string key = absl::HexStringToBytes(test.key_hex);
+    const std::string salt = absl::HexStringToBytes(test.salt_hex);
+    const std::string info = absl::HexStringToBytes(test.info_hex);
+    const std::string expected = absl::HexStringToBytes(test.output_hex);
 
     // We set the key_length to the length of the expected output and then take
     // the result from the first key, which is the client write key.
diff --git a/quic/core/crypto/transport_parameters.cc b/quic/core/crypto/transport_parameters.cc
index b143d9d..c047e0f 100644
--- a/quic/core/crypto/transport_parameters.cc
+++ b/quic/core/crypto/transport_parameters.cc
@@ -10,6 +10,7 @@
 #include <memory>
 #include <utility>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "third_party/boringssl/src/include/openssl/digest.h"
 #include "third_party/boringssl/src/include/openssl/sha.h"
@@ -394,9 +395,9 @@
   return "[" + ipv4_socket_address.ToString() + " " +
          ipv6_socket_address.ToString() + " connection_id " +
          connection_id.ToString() + " stateless_reset_token " +
-         quiche::QuicheTextUtils::HexEncode(
+         absl::BytesToHexString(absl::string_view(
              reinterpret_cast<const char*>(stateless_reset_token.data()),
-             stateless_reset_token.size()) +
+             stateless_reset_token.size())) +
          "]";
 }
 
@@ -426,9 +427,9 @@
   rv += max_idle_timeout_ms.ToString(/*for_use_in_list=*/true);
   if (!stateless_reset_token.empty()) {
     rv += " " + TransportParameterIdToString(kStatelessResetToken) + " " +
-          quiche::QuicheTextUtils::HexEncode(
+          absl::BytesToHexString(absl::string_view(
               reinterpret_cast<const char*>(stateless_reset_token.data()),
-              stateless_reset_token.size());
+              stateless_reset_token.size()));
   }
   rv += max_udp_payload_size.ToString(/*for_use_in_list=*/true);
   rv += initial_max_data.ToString(/*for_use_in_list=*/true);
@@ -485,10 +486,10 @@
     rv += "=";
     static constexpr size_t kMaxPrintableLength = 32;
     if (kv.second.length() <= kMaxPrintableLength) {
-      rv += quiche::QuicheTextUtils::HexEncode(kv.second);
+      rv += absl::BytesToHexString(kv.second);
     } else {
       absl::string_view truncated(kv.second.data(), kMaxPrintableLength);
-      rv += quiche::QuicheStrCat(quiche::QuicheTextUtils::HexEncode(truncated),
+      rv += quiche::QuicheStrCat(absl::BytesToHexString(truncated),
                                  "...(length ", kv.second.length(), ")");
     }
   }
diff --git a/quic/core/frames/quic_new_token_frame.cc b/quic/core/frames/quic_new_token_frame.cc
index 0178422..6806cda 100644
--- a/quic/core/frames/quic_new_token_frame.cc
+++ b/quic/core/frames/quic_new_token_frame.cc
@@ -4,6 +4,7 @@
 
 #include "net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.h"
 
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
 
@@ -15,7 +16,7 @@
 
 std::ostream& operator<<(std::ostream& os, const QuicNewTokenFrame& s) {
   os << "{ control_frame_id: " << s.control_frame_id
-     << ", token: " << quiche::QuicheTextUtils::HexEncode(s.token) << " }\n";
+     << ", token: " << absl::BytesToHexString(s.token) << " }\n";
   return os;
 }
 
diff --git a/quic/core/frames/quic_path_challenge_frame.cc b/quic/core/frames/quic_path_challenge_frame.cc
index 4a8d120..eb841b2 100644
--- a/quic/core/frames/quic_path_challenge_frame.cc
+++ b/quic/core/frames/quic_path_challenge_frame.cc
@@ -4,6 +4,7 @@
 
 #include "net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h"
 
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
 
@@ -21,9 +22,9 @@
 std::ostream& operator<<(std::ostream& os,
                          const QuicPathChallengeFrame& frame) {
   os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
-     << quiche::QuicheTextUtils::HexEncode(
+     << absl::BytesToHexString(absl::string_view(
             reinterpret_cast<const char*>(frame.data_buffer.data()),
-            frame.data_buffer.size())
+            frame.data_buffer.size()))
      << " }\n";
   return os;
 }
diff --git a/quic/core/frames/quic_path_response_frame.cc b/quic/core/frames/quic_path_response_frame.cc
index 4779c6a..1623777 100644
--- a/quic/core/frames/quic_path_response_frame.cc
+++ b/quic/core/frames/quic_path_response_frame.cc
@@ -4,6 +4,7 @@
 
 #include "net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.h"
 
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
 
@@ -20,9 +21,9 @@
 
 std::ostream& operator<<(std::ostream& os, const QuicPathResponseFrame& frame) {
   os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
-     << quiche::QuicheTextUtils::HexEncode(
+     << absl::BytesToHexString(absl::string_view(
             reinterpret_cast<const char*>(frame.data_buffer.data()),
-            frame.data_buffer.size())
+            frame.data_buffer.size()))
      << " }\n";
   return os;
 }
diff --git a/quic/core/http/http_decoder_test.cc b/quic/core/http/http_decoder_test.cc
index 9558b9a..7702b0d 100644
--- a/quic/core/http/http_decoder_test.cc
+++ b/quic/core/http/http_decoder_test.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/http/http_encoder.h"
 #include "net/third_party/quiche/src/quic/core/http/http_frames.h"
@@ -229,7 +230,7 @@
 
 TEST_F(HttpDecoderTest, CancelPush) {
   InSequence s;
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "03"    // type (CANCEL_PUSH)
       "01"    // length
       "01");  // Push Id
@@ -257,10 +258,10 @@
 TEST_F(HttpDecoderTest, PushPromiseFrame) {
   InSequence s;
   std::string input = quiche::QuicheStrCat(
-      quiche::QuicheTextUtils::HexDecode("05"  // type (PUSH PROMISE)
-                                         "0f"  // length
-                                         "C000000000000101"),  // push id 257
-      "Headers");                                              // headers
+      absl::HexStringToBytes("05"                  // type (PUSH PROMISE)
+                             "0f"                  // length
+                             "C000000000000101"),  // push id 257
+      "Headers");                                  // headers
 
   // Visitor pauses processing.
   EXPECT_CALL(visitor_, OnPushPromiseFrameStart(2)).WillOnce(Return(false));
@@ -325,7 +326,7 @@
 TEST_F(HttpDecoderTest, CorruptPushPromiseFrame) {
   InSequence s;
 
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "05"    // type (PUSH_PROMISE)
       "01"    // length
       "40");  // first byte of two-byte varint push id
@@ -356,7 +357,7 @@
 
 TEST_F(HttpDecoderTest, MaxPushId) {
   InSequence s;
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "0D"    // type (MAX_PUSH_ID)
       "01"    // length
       "01");  // Push Id
@@ -383,7 +384,7 @@
 
 TEST_F(HttpDecoderTest, SettingsFrame) {
   InSequence s;
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "04"    // type (SETTINGS)
       "07"    // length
       "01"    // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
@@ -463,7 +464,7 @@
 }
 
 TEST_F(HttpDecoderTest, DuplicateSettingsIdentifier) {
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "04"    // type (SETTINGS)
       "04"    // length
       "01"    // identifier
@@ -483,10 +484,10 @@
 
 TEST_F(HttpDecoderTest, DataFrame) {
   InSequence s;
-  std::string input = quiche::QuicheStrCat(
-      quiche::QuicheTextUtils::HexDecode("00"    // type (DATA)
-                                         "05"),  // length
-      "Data!");                                  // data
+  std::string input =
+      quiche::QuicheStrCat(absl::HexStringToBytes("00"    // type (DATA)
+                                                  "05"),  // length
+                           "Data!");                      // data
 
   // Visitor pauses processing.
   EXPECT_CALL(visitor_, OnDataFrameStart(2, 5)).WillOnce(Return(false));
@@ -585,7 +586,7 @@
 
 TEST_F(HttpDecoderTest, GoAway) {
   InSequence s;
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "07"    // type (GOAWAY)
       "01"    // length
       "01");  // ID
@@ -612,10 +613,10 @@
 
 TEST_F(HttpDecoderTest, HeadersFrame) {
   InSequence s;
-  std::string input = quiche::QuicheStrCat(
-      quiche::QuicheTextUtils::HexDecode("01"    // type (HEADERS)
-                                         "07"),  // length
-      "Headers");                                // headers
+  std::string input =
+      quiche::QuicheStrCat(absl::HexStringToBytes("01"    // type (HEADERS)
+                                                  "07"),  // length
+                           "Headers");                    // headers
 
   // Visitor pauses processing.
   EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7)).WillOnce(Return(false));
@@ -660,7 +661,7 @@
 
 TEST_F(HttpDecoderTest, EmptyDataFrame) {
   InSequence s;
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "00"    // type (DATA)
       "00");  // length
 
@@ -690,7 +691,7 @@
 
 TEST_F(HttpDecoderTest, EmptyHeadersFrame) {
   InSequence s;
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "01"    // type (HEADERS)
       "00");  // length
 
@@ -720,7 +721,7 @@
 
 TEST_F(HttpDecoderTest, PushPromiseFrameNoHeaders) {
   InSequence s;
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "05"    // type (PUSH_PROMISE)
       "01"    // length
       "01");  // Push Id
@@ -754,7 +755,7 @@
 }
 
 TEST_F(HttpDecoderTest, MalformedFrameWithOverlyLargePayload) {
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "03"    // type (CANCEL_PUSH)
       "10"    // length
       "15");  // malformed payload
@@ -782,7 +783,7 @@
 
 TEST_F(HttpDecoderTest, Http2Frame) {
   SetQuicReloadableFlag(quic_reject_spdy_frames, true);
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "06"    // PING in HTTP/2 but not supported in HTTP/3.
       "05"    // length
       "15");  // random payload
@@ -797,13 +798,13 @@
 
 TEST_F(HttpDecoderTest, HeadersPausedThenData) {
   InSequence s;
-  std::string input = quiche::QuicheStrCat(
-      quiche::QuicheTextUtils::HexDecode("01"    // type (HEADERS)
-                                         "07"),  // length
-      "Headers",                                 // headers
-      quiche::QuicheTextUtils::HexDecode("00"    // type (DATA)
-                                         "05"),  // length
-      "Data!");                                  // data
+  std::string input =
+      quiche::QuicheStrCat(absl::HexStringToBytes("01"    // type (HEADERS)
+                                                  "07"),  // length
+                           "Headers",                     // headers
+                           absl::HexStringToBytes("00"    // type (DATA)
+                                                  "05"),  // length
+                           "Data!");                      // data
 
   // Visitor pauses processing, maybe because header decompression is blocked.
   EXPECT_CALL(visitor_, OnHeadersFrameStart(2, 7));
@@ -886,7 +887,7 @@
 }
 
 TEST_F(HttpDecoderTest, EmptyCancelPushFrame) {
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "03"    // type (CANCEL_PUSH)
       "00");  // frame length
 
@@ -897,7 +898,7 @@
 }
 
 TEST_F(HttpDecoderTest, EmptySettingsFrame) {
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "04"    // type (SETTINGS)
       "00");  // frame length
 
@@ -913,7 +914,7 @@
 
 // Regression test for https://crbug.com/1001823.
 TEST_F(HttpDecoderTest, EmptyPushPromiseFrame) {
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "05"    // type (PUSH_PROMISE)
       "00");  // frame length
 
@@ -924,7 +925,7 @@
 }
 
 TEST_F(HttpDecoderTest, EmptyGoAwayFrame) {
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "07"    // type (GOAWAY)
       "00");  // frame length
 
@@ -935,7 +936,7 @@
 }
 
 TEST_F(HttpDecoderTest, EmptyMaxPushIdFrame) {
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "0d"    // type (MAX_PUSH_ID)
       "00");  // frame length
 
@@ -959,7 +960,7 @@
 
 TEST_F(HttpDecoderTest, PriorityUpdateFrame) {
   InSequence s;
-  std::string input1 = quiche::QuicheTextUtils::HexDecode(
+  std::string input1 = absl::HexStringToBytes(
       "0f"    // type (PRIORITY_UPDATE)
       "02"    // length
       "00"    // prioritized element type: REQUEST_STREAM
@@ -998,7 +999,7 @@
   EXPECT_THAT(decoder_.error(), IsQuicNoError());
   EXPECT_EQ("", decoder_.error_detail());
 
-  std::string input2 = quiche::QuicheTextUtils::HexDecode(
+  std::string input2 = absl::HexStringToBytes(
       "0f"        // type (PRIORIRTY)
       "05"        // length
       "80"        // prioritized element type: PUSH_STREAM
@@ -1040,11 +1041,11 @@
 }
 
 TEST_F(HttpDecoderTest, CorruptPriorityUpdateFrame) {
-  std::string payload1 = quiche::QuicheTextUtils::HexDecode(
+  std::string payload1 = absl::HexStringToBytes(
       "80"      // prioritized element type: PUSH_STREAM
       "4005");  // prioritized element id
-  std::string payload2 = quiche::QuicheTextUtils::HexDecode(
-      "42");  // invalid prioritized element type
+  std::string payload2 =
+      absl::HexStringToBytes("42");  // invalid prioritized element type
   struct {
     const char* const payload;
     size_t payload_length;
@@ -1076,7 +1077,7 @@
 }
 
 TEST_F(HttpDecoderTest, DecodeSettings) {
-  std::string input = quiche::QuicheTextUtils::HexDecode(
+  std::string input = absl::HexStringToBytes(
       "04"    // type (SETTINGS)
       "07"    // length
       "01"    // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
@@ -1096,7 +1097,7 @@
   EXPECT_EQ(frame, out);
 
   // non-settings frame.
-  input = quiche::QuicheTextUtils::HexDecode(
+  input = absl::HexStringToBytes(
       "0D"    // type (MAX_PUSH_ID)
       "01"    // length
       "01");  // Push Id
@@ -1104,7 +1105,7 @@
   EXPECT_FALSE(HttpDecoder::DecodeSettings(input.data(), input.size(), &out));
 
   // Corrupt SETTINGS.
-  input = quiche::QuicheTextUtils::HexDecode(
+  input = absl::HexStringToBytes(
       "04"    // type (SETTINGS)
       "01"    // length
       "42");  // First byte of setting identifier, indicating a 2-byte varint62.
diff --git a/quic/core/http/quic_receive_control_stream_test.cc b/quic/core/http/quic_receive_control_stream_test.cc
index 4aa3063..5a401b6 100644
--- a/quic/core/http/quic_receive_control_stream_test.cc
+++ b/quic/core/http/quic_receive_control_stream_test.cc
@@ -4,6 +4,7 @@
 
 #include "net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h"
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/http/http_constants.h"
 #include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h"
@@ -336,7 +337,7 @@
   EXPECT_EQ(offset, NumBytesConsumed());
 
   // Receive unknown frame.
-  std::string unknown_frame = quiche::QuicheTextUtils::HexDecode(
+  std::string unknown_frame = absl::HexStringToBytes(
       "21"        // reserved frame type
       "03"        // payload length
       "666f6f");  // payload "foo"
@@ -365,7 +366,7 @@
   offset += settings_frame.length();
 
   // Receive unknown frame.
-  std::string unknown_frame = quiche::QuicheTextUtils::HexDecode(
+  std::string unknown_frame = absl::HexStringToBytes(
       "21"        // reserved frame type
       "03"        // payload length
       "666f6f");  // payload "foo"
@@ -377,7 +378,7 @@
 }
 
 TEST_P(QuicReceiveControlStreamTest, CancelPushFrameBeforeSettings) {
-  std::string cancel_push_frame = quiche::QuicheTextUtils::HexDecode(
+  std::string cancel_push_frame = absl::HexStringToBytes(
       "03"    // type CANCEL_PUSH
       "01"    // payload length
       "01");  // push ID
@@ -396,7 +397,7 @@
 }
 
 TEST_P(QuicReceiveControlStreamTest, UnknownFrameBeforeSettings) {
-  std::string unknown_frame = quiche::QuicheTextUtils::HexDecode(
+  std::string unknown_frame = absl::HexStringToBytes(
       "21"        // reserved frame type
       "03"        // payload length
       "666f6f");  // payload "foo"
diff --git a/quic/core/http/quic_send_control_stream_test.cc b/quic/core/http/quic_send_control_stream_test.cc
index bc49107..53d0d6d 100644
--- a/quic/core/http/quic_send_control_stream_test.cc
+++ b/quic/core/http/quic_send_control_stream_test.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
@@ -113,7 +114,7 @@
   Initialize();
   testing::InSequence s;
 
-  std::string expected_write_data = quiche::QuicheTextUtils::HexDecode(
+  std::string expected_write_data = absl::HexStringToBytes(
       "00"    // stream type: control stream
       "04"    // frame type: SETTINGS frame
       "0b"    // frame length
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index d95fa6d..36ebf87 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -11,6 +11,7 @@
 #include <utility>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
 #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
@@ -1979,7 +1980,7 @@
   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
 
   // Push unidirectional stream is type 0x01.
-  std::string frame_type1 = quiche::QuicheTextUtils::HexDecode("01");
+  std::string frame_type1 = absl::HexStringToBytes("01");
   QuicStreamId stream_id1 =
       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
   session_.OnStreamFrame(QuicStreamFrame(stream_id1, /* fin = */ false,
@@ -1991,7 +1992,7 @@
   EXPECT_EQ(1u, session_.flow_controller()->bytes_consumed());
 
   // The same stream type can be encoded differently.
-  std::string frame_type2 = quiche::QuicheTextUtils::HexDecode("80000001");
+  std::string frame_type2 = absl::HexStringToBytes("80000001");
   QuicStreamId stream_id2 =
       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 1);
   session_.OnStreamFrame(QuicStreamFrame(stream_id2, /* fin = */ false,
@@ -2011,9 +2012,9 @@
   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_));
 
   // Push unidirectional stream is type 0x01.
-  std::string frame_type = quiche::QuicheTextUtils::HexDecode("01");
+  std::string frame_type = absl::HexStringToBytes("01");
   // The first field of a push stream is the Push ID.
-  std::string push_id = quiche::QuicheTextUtils::HexDecode("4000");
+  std::string push_id = absl::HexStringToBytes("4000");
 
   QuicStreamId stream_id =
       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
@@ -2485,7 +2486,7 @@
   TestStream* stream = session_.CreateIncomingStream(stream_id);
 
   // HEADERS frame referencing first dynamic table entry.
-  std::string headers_payload = quiche::QuicheTextUtils::HexDecode("020080");
+  std::string headers_payload = absl::HexStringToBytes("020080");
   std::unique_ptr<char[]> headers_buffer;
   QuicByteCount headers_frame_header_length =
       HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(),
@@ -2520,7 +2521,7 @@
   TestStream* stream = session_.CreateIncomingStream(stream_id);
 
   // HEADERS frame referencing first dynamic table entry.
-  std::string headers_payload = quiche::QuicheTextUtils::HexDecode("020080");
+  std::string headers_payload = absl::HexStringToBytes("020080");
   std::unique_ptr<char[]> headers_buffer;
   QuicByteCount headers_frame_header_length =
       HttpEncoder::SerializeHeadersFrameHeader(headers_payload.length(),
@@ -2553,7 +2554,7 @@
   // Payload consists of two bytes.  The first byte is an unknown unidirectional
   // stream type.  The second one would be the type of a push stream, but it
   // must not be interpreted as stream type.
-  std::string payload = quiche::QuicheTextUtils::HexDecode("3f01");
+  std::string payload = absl::HexStringToBytes("3f01");
   QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
                         payload);
 
@@ -2599,7 +2600,7 @@
   // Payload consists of two bytes.  The first byte is an unknown unidirectional
   // stream type.  The second one would be the type of a push stream, but it
   // must not be interpreted as stream type.
-  std::string payload = quiche::QuicheTextUtils::HexDecode("3f01");
+  std::string payload = absl::HexStringToBytes("3f01");
   QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
                         payload);
 
@@ -2636,7 +2637,7 @@
       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
 
   // Payload is the first byte of a two byte varint encoding.
-  std::string payload = quiche::QuicheTextUtils::HexDecode("40");
+  std::string payload = absl::HexStringToBytes("40");
   QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
                         payload);
 
@@ -2664,7 +2665,7 @@
       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
 
   // Payload is the first byte of a two byte varint encoding with a FIN.
-  std::string payload = quiche::QuicheTextUtils::HexDecode("40");
+  std::string payload = absl::HexStringToBytes("40");
   QuicStreamFrame frame(stream_id, /* fin = */ true, /* offset = */ 0, payload);
 
   session_.OnStreamFrame(frame);
@@ -2741,7 +2742,7 @@
     return;
   }
 
-  std::string data = quiche::QuicheTextUtils::HexDecode(
+  std::string data = absl::HexStringToBytes(
       "02"    // Encoder stream.
       "00");  // Duplicate entry 0, but no entries exist.
 
@@ -2765,7 +2766,7 @@
     return;
   }
 
-  std::string data = quiche::QuicheTextUtils::HexDecode(
+  std::string data = absl::HexStringToBytes(
       "03"    // Decoder stream.
       "00");  // Insert Count Increment with forbidden increment value of zero.
 
@@ -2920,7 +2921,7 @@
 
   // Index 126 does not exist (static table has 61 entries and dynamic table is
   // empty).
-  std::string headers_frame = quiche::QuicheTextUtils::HexDecode(
+  std::string headers_frame = absl::HexStringToBytes(
       "000006"    // length
       "01"        // type
       "24"        // flags: PRIORITY | END_HEADERS
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc
index 6cd7634..526b987 100644
--- a/quic/core/http/quic_spdy_stream_test.cc
+++ b/quic/core/http/quic_spdy_stream_test.cc
@@ -10,6 +10,7 @@
 #include <utility>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
 #include "net/third_party/quiche/src/quic/core/http/http_encoder.h"
@@ -696,7 +697,7 @@
   Initialize(kShouldProcessData);
 
   // PUSH_PROMISE frame with empty payload is considered invalid.
-  std::string invalid_http3_frame = quiche::QuicheTextUtils::HexDecode("0500");
+  std::string invalid_http3_frame = absl::HexStringToBytes("0500");
   QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
                                /* offset = */ 0, invalid_http3_frame);
 
@@ -712,7 +713,7 @@
   Initialize(kShouldProcessData);
 
   // SETTINGS frame with empty payload.
-  std::string settings = quiche::QuicheTextUtils::HexDecode("0400");
+  std::string settings = absl::HexStringToBytes("0400");
   QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
                                /* offset = */ 0, settings);
 
@@ -2088,7 +2089,7 @@
 
   // Random bad headers.
   std::string headers =
-      HeadersFrame(quiche::QuicheTextUtils::HexDecode("00002a94e7036261"));
+      HeadersFrame(absl::HexStringToBytes("00002a94e7036261"));
   std::string data = DataFrame(kDataFramePayload);
 
   std::string stream_frame_payload = quiche::QuicheStrCat(headers, data);
@@ -2164,8 +2165,7 @@
 
   // Invalid headers: Required Insert Count is zero, but the header block
   // contains a dynamic table reference.
-  std::string headers =
-      HeadersFrame(quiche::QuicheTextUtils::HexDecode("000080"));
+  std::string headers = HeadersFrame(absl::HexStringToBytes("000080"));
   QuicStreamFrame frame(stream_->id(), false, 0, headers);
   stream_->OnStreamFrame(frame);
 }
@@ -2188,7 +2188,7 @@
   session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
 
   // HEADERS frame referencing first dynamic table entry.
-  std::string encoded_headers = quiche::QuicheTextUtils::HexDecode("020080");
+  std::string encoded_headers = absl::HexStringToBytes("020080");
   std::string headers = HeadersFrame(encoded_headers);
   EXPECT_CALL(debug_visitor,
               OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
@@ -2222,7 +2222,7 @@
   session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
 
   // Trailing HEADERS frame referencing second dynamic table entry.
-  std::string encoded_trailers = quiche::QuicheTextUtils::HexDecode("030080");
+  std::string encoded_trailers = absl::HexStringToBytes("030080");
   std::string trailers = HeadersFrame(encoded_trailers);
   EXPECT_CALL(debug_visitor,
               OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
@@ -2254,7 +2254,7 @@
   session_->set_debug_visitor(&debug_visitor);
 
   // HEADERS frame referencing first dynamic table entry.
-  std::string encoded_headers = quiche::QuicheTextUtils::HexDecode("020080");
+  std::string encoded_headers = absl::HexStringToBytes("020080");
   std::string headers = HeadersFrame(encoded_headers);
   EXPECT_CALL(debug_visitor,
               OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
@@ -2292,7 +2292,7 @@
   EXPECT_EQ(kDataFramePayload, stream_->data());
 
   // Trailing HEADERS frame referencing second dynamic table entry.
-  std::string encoded_trailers = quiche::QuicheTextUtils::HexDecode("030080");
+  std::string encoded_trailers = absl::HexStringToBytes("030080");
   std::string trailers = HeadersFrame(encoded_trailers);
   EXPECT_CALL(debug_visitor,
               OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
@@ -2326,8 +2326,7 @@
 
   // HEADERS frame only referencing entry with absolute index 0 but with
   // Required Insert Count = 2, which is incorrect.
-  std::string headers =
-      HeadersFrame(quiche::QuicheTextUtils::HexDecode("030081"));
+  std::string headers = HeadersFrame(absl::HexStringToBytes("030081"));
   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
 
   // Even though entire header block is received and every referenced entry is
@@ -2359,8 +2358,7 @@
   session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
 
   // Relative index 2 is invalid because it is larger than or equal to the Base.
-  std::string headers =
-      HeadersFrame(quiche::QuicheTextUtils::HexDecode("020082"));
+  std::string headers = HeadersFrame(absl::HexStringToBytes("020082"));
   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
 
   // Decoding is blocked.
@@ -2388,8 +2386,7 @@
   session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
 
   // HEADERS frame referencing first dynamic table entry.
-  std::string headers =
-      HeadersFrame(quiche::QuicheTextUtils::HexDecode("020080"));
+  std::string headers = HeadersFrame(absl::HexStringToBytes("020080"));
   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
 
   // Decoding is blocked because dynamic table entry has not been received yet.
@@ -2422,8 +2419,7 @@
 
   // Trailing HEADERS frame only referencing entry with absolute index 0 but
   // with Required Insert Count = 2, which is incorrect.
-  std::string trailers =
-      HeadersFrame(quiche::QuicheTextUtils::HexDecode("030081"));
+  std::string trailers = HeadersFrame(absl::HexStringToBytes("030081"));
   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
                                          headers.length() + data.length(),
                                          trailers));
@@ -2459,7 +2455,7 @@
   session_->set_debug_visitor(&debug_visitor);
 
   // HEADERS frame referencing first dynamic table entry.
-  std::string encoded_headers = quiche::QuicheTextUtils::HexDecode("020080");
+  std::string encoded_headers = absl::HexStringToBytes("020080");
   std::string headers = HeadersFrame(encoded_headers);
   EXPECT_CALL(debug_visitor,
               OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
@@ -2903,7 +2899,7 @@
   Initialize(kShouldProcessData);
 
   // SETTINGS frame with empty payload.
-  std::string settings = quiche::QuicheTextUtils::HexDecode("0400");
+  std::string settings = absl::HexStringToBytes("0400");
 
   // HEADERS frame.
   // Since it arrives after a SETTINGS frame, it should never be read.
diff --git a/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc b/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
index eeb34eb..2a5b0da 100644
--- a/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
+++ b/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
@@ -6,6 +6,7 @@
 
 #include <cstring>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -84,7 +85,7 @@
 
 // HEADERS frame payload must have a complete Header Block Prefix.
 TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedHeaderBlockPrefix) {
-  accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("00"));
+  accumulator_.Decode(absl::HexStringToBytes("00"));
 
   EXPECT_CALL(visitor_,
               OnHeaderDecodingError(Eq("Incomplete header data prefix.")));
@@ -92,7 +93,7 @@
 }
 
 TEST_F(QpackDecodedHeadersAccumulatorTest, EmptyHeaderList) {
-  std::string encoded_data(quiche::QuicheTextUtils::HexDecode("0000"));
+  std::string encoded_data(absl::HexStringToBytes("0000"));
   accumulator_.Decode(encoded_data);
 
   QuicHeaderList header_list;
@@ -108,7 +109,7 @@
 // This payload is the prefix of a valid payload, but EndHeaderBlock() is called
 // before it can be completely decoded.
 TEST_F(QpackDecodedHeadersAccumulatorTest, TruncatedPayload) {
-  accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("00002366"));
+  accumulator_.Decode(absl::HexStringToBytes("00002366"));
 
   EXPECT_CALL(visitor_, OnHeaderDecodingError(Eq("Incomplete header block.")));
   accumulator_.EndHeaderBlock();
@@ -118,12 +119,11 @@
 TEST_F(QpackDecodedHeadersAccumulatorTest, InvalidPayload) {
   EXPECT_CALL(visitor_,
               OnHeaderDecodingError(Eq("Static table entry not found.")));
-  accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("0000ff23ff24"));
+  accumulator_.Decode(absl::HexStringToBytes("0000ff23ff24"));
 }
 
 TEST_F(QpackDecodedHeadersAccumulatorTest, Success) {
-  std::string encoded_data(
-      quiche::QuicheTextUtils::HexDecode("000023666f6f03626172"));
+  std::string encoded_data(absl::HexStringToBytes("000023666f6f03626172"));
   accumulator_.Decode(encoded_data);
 
   QuicHeaderList header_list;
@@ -141,7 +141,7 @@
 // otherwise decoding could fail with "incomplete header block" error.
 TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitThenSplitInstruction) {
   // Total length of header list exceeds kMaxHeaderListSize.
-  accumulator_.Decode(quiche::QuicheTextUtils::HexDecode(
+  accumulator_.Decode(absl::HexStringToBytes(
       "0000"                                      // header block prefix
       "26666f6f626172"                            // header key: "foobar"
       "7d61616161616161616161616161616161616161"  // header value: 'a' 125 times
@@ -149,7 +149,7 @@
       "616161616161616161616161616161616161616161616161616161616161616161616161"
       "61616161616161616161616161616161616161616161616161616161616161616161"
       "ff"));  // first byte of a two-byte long Indexed Header Field instruction
-  accumulator_.Decode(quiche::QuicheTextUtils::HexDecode(
+  accumulator_.Decode(absl::HexStringToBytes(
       "0f"  // second byte of a two-byte long Indexed Header Field instruction
       ));
 
@@ -160,7 +160,7 @@
 // Test that header list limit enforcement works with blocked encoding.
 TEST_F(QpackDecodedHeadersAccumulatorTest, ExceedLimitBlocked) {
   // Total length of header list exceeds kMaxHeaderListSize.
-  accumulator_.Decode(quiche::QuicheTextUtils::HexDecode(
+  accumulator_.Decode(absl::HexStringToBytes(
       "0200"            // header block prefix
       "80"              // reference to dynamic table entry not yet received
       "26666f6f626172"  // header key: "foobar"
@@ -182,7 +182,7 @@
 
 TEST_F(QpackDecodedHeadersAccumulatorTest, BlockedDecoding) {
   // Reference to dynamic table entry not yet received.
-  std::string encoded_data(quiche::QuicheTextUtils::HexDecode("020080"));
+  std::string encoded_data(absl::HexStringToBytes("020080"));
   accumulator_.Decode(encoded_data);
   accumulator_.EndHeaderBlock();
 
@@ -206,7 +206,7 @@
 TEST_F(QpackDecodedHeadersAccumulatorTest,
        BlockedDecodingUnblockedBeforeEndOfHeaderBlock) {
   // Reference to dynamic table entry not yet received.
-  accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("020080"));
+  accumulator_.Decode(absl::HexStringToBytes("020080"));
 
   // Set dynamic table capacity.
   qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
@@ -216,7 +216,7 @@
   // Rest of header block: same entry again.
   EXPECT_CALL(decoder_stream_sender_delegate_,
               WriteStreamData(Eq(kHeaderAcknowledgement)));
-  accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("80"));
+  accumulator_.Decode(absl::HexStringToBytes("80"));
 
   QuicHeaderList header_list;
   EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
@@ -231,12 +231,12 @@
        BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
   // Required Insert Count higher than number of entries causes decoding to be
   // blocked.
-  accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("0200"));
+  accumulator_.Decode(absl::HexStringToBytes("0200"));
   // Indexed Header Field instruction addressing dynamic table entry with
   // relative index 0, absolute index 0.
-  accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("80"));
+  accumulator_.Decode(absl::HexStringToBytes("80"));
   // Relative index larger than or equal to Base is invalid.
-  accumulator_.Decode(quiche::QuicheTextUtils::HexDecode("81"));
+  accumulator_.Decode(absl::HexStringToBytes("81"));
 
   // Set dynamic table capacity.
   qpack_decoder_.OnSetDynamicTableCapacity(kMaxDynamicTableCapacity);
diff --git a/quic/core/qpack/qpack_decoder_stream_receiver_test.cc b/quic/core/qpack/qpack_decoder_stream_receiver_test.cc
index af8af8c..fd79595 100644
--- a/quic/core/qpack/qpack_decoder_stream_receiver_test.cc
+++ b/quic/core/qpack/qpack_decoder_stream_receiver_test.cc
@@ -4,6 +4,7 @@
 
 #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h"
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
@@ -42,59 +43,59 @@
 
 TEST_F(QpackDecoderStreamReceiverTest, InsertCountIncrement) {
   EXPECT_CALL(delegate_, OnInsertCountIncrement(0));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("00"));
+  stream_.Decode(absl::HexStringToBytes("00"));
 
   EXPECT_CALL(delegate_, OnInsertCountIncrement(10));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("0a"));
+  stream_.Decode(absl::HexStringToBytes("0a"));
 
   EXPECT_CALL(delegate_, OnInsertCountIncrement(63));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("3f00"));
+  stream_.Decode(absl::HexStringToBytes("3f00"));
 
   EXPECT_CALL(delegate_, OnInsertCountIncrement(200));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("3f8901"));
+  stream_.Decode(absl::HexStringToBytes("3f8901"));
 
   EXPECT_CALL(delegate_,
               OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
                               Eq("Encoded integer too large.")));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("3fffffffffffffffffffff"));
+  stream_.Decode(absl::HexStringToBytes("3fffffffffffffffffffff"));
 }
 
 TEST_F(QpackDecoderStreamReceiverTest, HeaderAcknowledgement) {
   EXPECT_CALL(delegate_, OnHeaderAcknowledgement(0));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("80"));
+  stream_.Decode(absl::HexStringToBytes("80"));
 
   EXPECT_CALL(delegate_, OnHeaderAcknowledgement(37));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("a5"));
+  stream_.Decode(absl::HexStringToBytes("a5"));
 
   EXPECT_CALL(delegate_, OnHeaderAcknowledgement(127));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("ff00"));
+  stream_.Decode(absl::HexStringToBytes("ff00"));
 
   EXPECT_CALL(delegate_, OnHeaderAcknowledgement(503));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("fff802"));
+  stream_.Decode(absl::HexStringToBytes("fff802"));
 
   EXPECT_CALL(delegate_,
               OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
                               Eq("Encoded integer too large.")));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("ffffffffffffffffffffff"));
+  stream_.Decode(absl::HexStringToBytes("ffffffffffffffffffffff"));
 }
 
 TEST_F(QpackDecoderStreamReceiverTest, StreamCancellation) {
   EXPECT_CALL(delegate_, OnStreamCancellation(0));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("40"));
+  stream_.Decode(absl::HexStringToBytes("40"));
 
   EXPECT_CALL(delegate_, OnStreamCancellation(19));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("53"));
+  stream_.Decode(absl::HexStringToBytes("53"));
 
   EXPECT_CALL(delegate_, OnStreamCancellation(63));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("7f00"));
+  stream_.Decode(absl::HexStringToBytes("7f00"));
 
   EXPECT_CALL(delegate_, OnStreamCancellation(110));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("7f2f"));
+  stream_.Decode(absl::HexStringToBytes("7f2f"));
 
   EXPECT_CALL(delegate_,
               OnErrorDetected(QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE,
                               Eq("Encoded integer too large.")));
-  stream_.Decode(quiche::QuicheTextUtils::HexDecode("7fffffffffffffffffffff"));
+  stream_.Decode(absl::HexStringToBytes("7fffffffffffffffffffff"));
 }
 
 }  // namespace
diff --git a/quic/core/qpack/qpack_decoder_stream_sender_test.cc b/quic/core/qpack/qpack_decoder_stream_sender_test.cc
index 1d18fa9..c412c9f 100644
--- a/quic/core/qpack/qpack_decoder_stream_sender_test.cc
+++ b/quic/core/qpack/qpack_decoder_stream_sender_test.cc
@@ -4,6 +4,7 @@
 
 #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.h"
 
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
 #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
@@ -27,67 +28,55 @@
 };
 
 TEST_F(QpackDecoderStreamSenderTest, InsertCountIncrement) {
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("00"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("00"))));
   stream_.SendInsertCountIncrement(0);
   stream_.Flush();
 
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("0a"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0a"))));
   stream_.SendInsertCountIncrement(10);
   stream_.Flush();
 
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("3f00"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f00"))));
   stream_.SendInsertCountIncrement(63);
   stream_.Flush();
 
-  EXPECT_CALL(delegate_, WriteStreamData(
-                             Eq(quiche::QuicheTextUtils::HexDecode("3f8901"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("3f8901"))));
   stream_.SendInsertCountIncrement(200);
   stream_.Flush();
 }
 
 TEST_F(QpackDecoderStreamSenderTest, HeaderAcknowledgement) {
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("80"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("80"))));
   stream_.SendHeaderAcknowledgement(0);
   stream_.Flush();
 
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("a5"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("a5"))));
   stream_.SendHeaderAcknowledgement(37);
   stream_.Flush();
 
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("ff00"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("ff00"))));
   stream_.SendHeaderAcknowledgement(127);
   stream_.Flush();
 
-  EXPECT_CALL(delegate_, WriteStreamData(
-                             Eq(quiche::QuicheTextUtils::HexDecode("fff802"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("fff802"))));
   stream_.SendHeaderAcknowledgement(503);
   stream_.Flush();
 }
 
 TEST_F(QpackDecoderStreamSenderTest, StreamCancellation) {
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("40"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("40"))));
   stream_.SendStreamCancellation(0);
   stream_.Flush();
 
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("53"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("53"))));
   stream_.SendStreamCancellation(19);
   stream_.Flush();
 
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("7f00"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f00"))));
   stream_.SendStreamCancellation(63);
   stream_.Flush();
 
-  EXPECT_CALL(delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("7f2f"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("7f2f"))));
   stream_.SendStreamCancellation(110);
   stream_.Flush();
 }
@@ -97,16 +86,14 @@
   stream_.SendHeaderAcknowledgement(37);
   stream_.SendStreamCancellation(0);
 
-  EXPECT_CALL(delegate_, WriteStreamData(
-                             Eq(quiche::QuicheTextUtils::HexDecode("0aa540"))));
+  EXPECT_CALL(delegate_, WriteStreamData(Eq(absl::HexStringToBytes("0aa540"))));
   stream_.Flush();
 
   stream_.SendInsertCountIncrement(63);
   stream_.SendStreamCancellation(110);
 
-  EXPECT_CALL(
-      delegate_,
-      WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("3f007f2f"))));
+  EXPECT_CALL(delegate_,
+              WriteStreamData(Eq(absl::HexStringToBytes("3f007f2f"))));
   stream_.Flush();
 }
 
diff --git a/quic/core/qpack/qpack_decoder_test.cc b/quic/core/qpack/qpack_decoder_test.cc
index 988ba8f..cf7c9d3 100644
--- a/quic/core/qpack/qpack_decoder_test.cc
+++ b/quic/core/qpack/qpack_decoder_test.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
@@ -117,7 +118,7 @@
               OnDecodingErrorDetected(Eq("Incomplete header data prefix.")));
 
   // Header Data Prefix is at least two bytes long.
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("00"));
+  DecodeHeaderBlock(absl::HexStringToBytes("00"));
 }
 
 // Regression test for https://1025209: QpackProgressiveDecoder must not crash
@@ -129,42 +130,41 @@
               OnDecodingErrorDetected(Eq("Encoded integer too large.")));
 
   // Encoded Required Insert Count in Header Data Prefix is too large.
-  DecodeData(
-      quiche::QuicheTextUtils::HexDecode("ffffffffffffffffffffffffffff"));
+  DecodeData(absl::HexStringToBytes("ffffffffffffffffffffffffffff"));
 }
 
 TEST_P(QpackDecoderTest, EmptyHeaderBlock) {
   EXPECT_CALL(handler_, OnDecodingCompleted());
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("0000"));
+  DecodeHeaderBlock(absl::HexStringToBytes("0000"));
 }
 
 TEST_P(QpackDecoderTest, LiteralEntryEmptyName) {
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("foo")));
   EXPECT_CALL(handler_, OnDecodingCompleted());
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("00002003666f6f"));
+  DecodeHeaderBlock(absl::HexStringToBytes("00002003666f6f"));
 }
 
 TEST_P(QpackDecoderTest, LiteralEntryEmptyValue) {
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("")));
   EXPECT_CALL(handler_, OnDecodingCompleted());
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("000023666f6f00"));
+  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f00"));
 }
 
 TEST_P(QpackDecoderTest, LiteralEntryEmptyNameAndValue) {
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(""), Eq("")));
   EXPECT_CALL(handler_, OnDecodingCompleted());
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("00002000"));
+  DecodeHeaderBlock(absl::HexStringToBytes("00002000"));
 }
 
 TEST_P(QpackDecoderTest, SimpleLiteralEntry) {
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
   EXPECT_CALL(handler_, OnDecodingCompleted());
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("000023666f6f03626172"));
+  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f03626172"));
 }
 
 TEST_P(QpackDecoderTest, MultipleLiteralEntries) {
@@ -173,7 +173,7 @@
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foobaar"), absl::string_view(str)));
   EXPECT_CALL(handler_, OnDecodingCompleted());
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0000"                // prefix
       "23666f6f03626172"    // foo: bar
       "2700666f6f62616172"  // 7 octet long header name, the smallest number
@@ -191,8 +191,7 @@
   EXPECT_CALL(handler_,
               OnDecodingErrorDetected(Eq("Encoded integer too large.")));
 
-  DecodeHeaderBlock(
-      quiche::QuicheTextUtils::HexDecode("000027ffffffffffffffffffff"));
+  DecodeHeaderBlock(absl::HexStringToBytes("000027ffffffffffffffffffff"));
 }
 
 // Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
@@ -200,7 +199,7 @@
   EXPECT_CALL(handler_,
               OnDecodingErrorDetected(Eq("String literal too long.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("000027ffff7f"));
+  DecodeHeaderBlock(absl::HexStringToBytes("000027ffff7f"));
 }
 
 // Value Length value is too large for varint decoder to decode.
@@ -209,7 +208,7 @@
               OnDecodingErrorDetected(Eq("Encoded integer too large.")));
 
   DecodeHeaderBlock(
-      quiche::QuicheTextUtils::HexDecode("000023666f6f7fffffffffffffffffffff"));
+      absl::HexStringToBytes("000023666f6f7fffffffffffffffffffff"));
 }
 
 // Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
@@ -217,22 +216,22 @@
   EXPECT_CALL(handler_,
               OnDecodingErrorDetected(Eq("String literal too long.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("000023666f6f7fffff7f"));
+  DecodeHeaderBlock(absl::HexStringToBytes("000023666f6f7fffff7f"));
 }
 
 TEST_P(QpackDecoderTest, IncompleteHeaderBlock) {
   EXPECT_CALL(handler_,
               OnDecodingErrorDetected(Eq("Incomplete header block.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("00002366"));
+  DecodeHeaderBlock(absl::HexStringToBytes("00002366"));
 }
 
 TEST_P(QpackDecoderTest, HuffmanSimple) {
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("custom-key"), Eq("custom-value")));
   EXPECT_CALL(handler_, OnDecodingCompleted());
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
-      "00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf"));
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf"));
 }
 
 TEST_P(QpackDecoderTest, AlternatingHuffmanNonHuffman) {
@@ -240,7 +239,7 @@
       .Times(4);
   EXPECT_CALL(handler_, OnDecodingCompleted());
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0000"                        // Prefix.
       "2f0125a849e95ba97d7f"        // Huffman-encoded name.
       "8925a849e95bb8e8b4bf"        // Huffman-encoded value.
@@ -258,8 +257,8 @@
 
   // 'y' ends in 0b0 on the most significant bit of the last byte.
   // The remaining 7 bits must be a prefix of EOS, which is all 1s.
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
-      "00002f0125a849e95ba97d7e8925a849e95bb8e8b4bf"));
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7e8925a849e95bb8e8b4bf"));
 }
 
 TEST_P(QpackDecoderTest, HuffmanValueDoesNotHaveEOSPrefix) {
@@ -268,8 +267,8 @@
 
   // 'e' ends in 0b101, taking up the 3 most significant bits of the last byte.
   // The remaining 5 bits must be a prefix of EOS, which is all 1s.
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
-      "00002f0125a849e95ba97d7f8925a849e95bb8e8b4be"));
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7f8925a849e95bb8e8b4be"));
 }
 
 TEST_P(QpackDecoderTest, HuffmanNameEOSPrefixTooLong) {
@@ -279,8 +278,8 @@
   // The trailing EOS prefix must be at most 7 bits long.  Appending one octet
   // with value 0xff is invalid, even though 0b111111111111111 (15 bits) is a
   // prefix of EOS.
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
-      "00002f0225a849e95ba97d7fff8925a849e95bb8e8b4bf"));
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0225a849e95ba97d7fff8925a849e95bb8e8b4bf"));
 }
 
 TEST_P(QpackDecoderTest, HuffmanValueEOSPrefixTooLong) {
@@ -290,8 +289,8 @@
   // The trailing EOS prefix must be at most 7 bits long.  Appending one octet
   // with value 0xff is invalid, even though 0b1111111111111 (13 bits) is a
   // prefix of EOS.
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
-      "00002f0125a849e95ba97d7f8a25a849e95bb8e8b4bfff"));
+  DecodeHeaderBlock(
+      absl::HexStringToBytes("00002f0125a849e95ba97d7f8a25a849e95bb8e8b4bfff"));
 }
 
 TEST_P(QpackDecoderTest, StaticTable) {
@@ -312,7 +311,7 @@
 
   EXPECT_CALL(handler_, OnDecodingCompleted());
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0000d1dfccd45f108621e9aec2a11f5c8294e75f000554524143455f1000"));
 }
 
@@ -325,11 +324,11 @@
   EXPECT_CALL(handler_,
               OnDecodingErrorDetected(Eq("Static table entry not found.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("0000ff23ff24"));
+  DecodeHeaderBlock(absl::HexStringToBytes("0000ff23ff24"));
 }
 
 TEST_P(QpackDecoderTest, DynamicTable) {
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode(
+  DecodeEncoderStreamData(absl::HexStringToBytes(
       "3fe107"          // Set dynamic table capacity to 1024.
       "6294e703626172"  // Add literal entry with name "foo" and value "bar".
       "80035a5a5a"      // Add entry with name of dynamic table entry index 0
@@ -358,7 +357,7 @@
       .InSequence(s);
   EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0500"  // Required Insert Count 4 and Delta Base 0.
               // Base is 4 + 0 = 4.
       "83"    // Dynamic table entry with relative index 3, absolute index 0.
@@ -379,7 +378,7 @@
       .InSequence(s);
   EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0502"  // Required Insert Count 4 and Delta Base 2.
               // Base is 4 + 2 = 6.
       "85"    // Dynamic table entry with relative index 5, absolute index 0.
@@ -400,7 +399,7 @@
       .InSequence(s);
   EXPECT_CALL(handler_, OnDecodingCompleted()).InSequence(s);
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0582"  // Required Insert Count 4 and Delta Base 2 with sign bit set.
               // Base is 4 - 2 - 1 = 1.
       "80"    // Dynamic table entry with relative index 0, absolute index 0.
@@ -413,28 +412,28 @@
 
 TEST_P(QpackDecoderTest, DecreasingDynamicTableCapacityEvictsEntries) {
   // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
   // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
 
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
   EXPECT_CALL(handler_, OnDecodingCompleted());
   EXPECT_CALL(decoder_stream_sender_delegate_,
               WriteStreamData(Eq(kHeaderAcknowledgement)));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0200"   // Required Insert Count 1 and Delta Base 0.
                // Base is 1 + 0 = 1.
       "80"));  // Dynamic table entry with relative index 0, absolute index 0.
 
   // Change dynamic table capacity to 32 bytes, smaller than the entry.
   // This must cause the entry to be evicted.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3f01"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f01"));
 
   EXPECT_CALL(handler_, OnDecodingErrorDetected(
                             Eq("Dynamic table entry already evicted.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0200"   // Required Insert Count 1 and Delta Base 0.
                // Base is 1 + 0 = 1.
       "80"));  // Dynamic table entry with relative index 0, absolute index 0.
@@ -449,9 +448,9 @@
                   Eq("Error inserting literal entry.")));
 
   // Set dynamic table capacity to 34.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3f03"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f03"));
   // Add literal entry with name "foo" and value "bar", size is 32 + 3 + 3 = 38.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
 }
 
 TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidStaticTableEntry) {
@@ -463,7 +462,7 @@
                   Eq("Invalid static table entry.")));
 
   // Address invalid static table entry index 99.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("ff2400"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("ff2400"));
 }
 
 TEST_P(QpackDecoderTest, EncoderStreamErrorInvalidDynamicTableEntry) {
@@ -475,7 +474,7 @@
               : QUIC_QPACK_ENCODER_STREAM_ERROR,
           Eq("Invalid relative index.")));
 
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode(
+  DecodeEncoderStreamData(absl::HexStringToBytes(
       "3fe107"          // Set dynamic table capacity to 1024.
       "6294e703626172"  // Add literal entry with name "foo" and value "bar".
       "8100"));  // Address dynamic table entry with relative index 1.  Such
@@ -492,7 +491,7 @@
               : QUIC_QPACK_ENCODER_STREAM_ERROR,
           Eq("Invalid relative index.")));
 
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode(
+  DecodeEncoderStreamData(absl::HexStringToBytes(
       "3fe107"          // Set dynamic table capacity to 1024.
       "6294e703626172"  // Add literal entry with name "foo" and value "bar".
       "01"));  // Duplicate dynamic table entry with relative index 1.  Such
@@ -508,19 +507,18 @@
                       : QUIC_QPACK_ENCODER_STREAM_ERROR,
                   Eq("Encoded integer too large.")));
 
-  DecodeEncoderStreamData(
-      quiche::QuicheTextUtils::HexDecode("3fffffffffffffffffffff"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fffffffffffffffffffff"));
 }
 
 TEST_P(QpackDecoderTest, InvalidDynamicEntryWhenBaseIsZero) {
   EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Invalid relative index.")));
 
   // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
   // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0280"   // Required Insert Count is 1.  Base 1 - 1 - 0 = 0 is explicitly
                // permitted by the spec.
       "80"));  // However, addressing entry with relative index 0 would point to
@@ -532,18 +530,18 @@
 
   // Required Insert Count 1, Delta Base 1 with sign bit set, Base would
   // be 1 - 1 - 1 = -1, but it is not allowed to be negative.
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("0281"));
+  DecodeHeaderBlock(absl::HexStringToBytes("0281"));
 }
 
 TEST_P(QpackDecoderTest, InvalidDynamicEntryByRelativeIndex) {
   // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
   // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
 
   EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Invalid relative index.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0200"   // Required Insert Count 1 and Delta Base 0.
                // Base is 1 + 0 = 1.
       "81"));  // Indexed Header Field instruction addressing relative index 1.
@@ -551,7 +549,7 @@
 
   EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Invalid relative index.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0200"     // Required Insert Count 1 and Delta Base 0.
                  // Base is 1 + 0 = 1.
       "4100"));  // Literal Header Field with Name Reference instruction
@@ -561,18 +559,18 @@
 
 TEST_P(QpackDecoderTest, EvictedDynamicTableEntry) {
   // Update dynamic table capacity to 128.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3f61"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
 
   // Add literal entry with name "foo" and value "bar", size 32 + 3 + 3 = 38.
   // This fits in the table three times.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
   // Duplicate entry four times.  This evicts the first two instances.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("00000000"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
 
   EXPECT_CALL(handler_, OnDecodingErrorDetected(
                             Eq("Dynamic table entry already evicted.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0500"   // Required Insert Count 4 and Delta Base 0.
                // Base is 4 + 0 = 4.
       "82"));  // Indexed Header Field instruction addressing relative index 2.
@@ -581,7 +579,7 @@
   EXPECT_CALL(handler_, OnDecodingErrorDetected(
                             Eq("Dynamic table entry already evicted.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0500"     // Required Insert Count 4 and Delta Base 0.
                  // Base is 4 + 0 = 4.
       "4200"));  // Literal Header Field with Name Reference instruction
@@ -591,7 +589,7 @@
   EXPECT_CALL(handler_, OnDecodingErrorDetected(
                             Eq("Dynamic table entry already evicted.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0380"   // Required Insert Count 2 and Delta Base 0 with sign bit set.
                // Base is 2 - 0 - 1 = 1
       "10"));  // Indexed Header Field instruction addressing dynamic table
@@ -601,7 +599,7 @@
   EXPECT_CALL(handler_, OnDecodingErrorDetected(
                             Eq("Dynamic table entry already evicted.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0380"     // Required Insert Count 2 and Delta Base 0 with sign bit set.
                  // Base is 2 - 0 - 1 = 1
       "0000"));  // Literal Header Field With Name Reference instruction
@@ -618,12 +616,12 @@
                   Eq("Error updating dynamic table capacity.")));
 
   // Try to update dynamic table capacity to 2048, which exceeds the maximum.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe10f"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe10f"));
 }
 
 TEST_P(QpackDecoderTest, SetDynamicTableCapacity) {
   // Update dynamic table capacity to 128, which does not exceed the maximum.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3f61"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
 }
 
 TEST_P(QpackDecoderTest, InvalidEncodedRequiredInsertCount) {
@@ -633,7 +631,7 @@
   // A value of 1 cannot be encoded as 65 even though it has the same remainder.
   EXPECT_CALL(handler_, OnDecodingErrorDetected(
                             Eq("Error decoding Required Insert Count.")));
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("4100"));
+  DecodeHeaderBlock(absl::HexStringToBytes("4100"));
 }
 
 // Regression test for https://crbug.com/970218:  Decoder must stop processing
@@ -642,7 +640,7 @@
   EXPECT_CALL(handler_, OnDecodingErrorDetected(
                             Eq("Error decoding Required Insert Count.")));
   // Header Block Prefix followed by some extra data.
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode("410000"));
+  DecodeHeaderBlock(absl::HexStringToBytes("410000"));
 }
 
 TEST_P(QpackDecoderTest, WrappedRequiredInsertCount) {
@@ -650,12 +648,12 @@
   // MaxEntries is 1024 / 32 = 32.
 
   // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
   // Add literal entry with name "foo" and a 600 byte long value.  This will fit
   // in the dynamic table once but not twice.
   DecodeEncoderStreamData(
-      quiche::QuicheTextUtils::HexDecode("6294e7"     // Name "foo".
-                                         "7fd903"));  // Value length 600.
+      absl::HexStringToBytes("6294e7"     // Name "foo".
+                             "7fd903"));  // Value length 600.
   std::string header_value(600, 'Z');
   DecodeEncoderStreamData(header_value);
 
@@ -670,7 +668,7 @@
               WriteStreamData(Eq(kHeaderAcknowledgement)));
 
   // Send header block with Required Insert Count = 201.
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0a00"   // Encoded Required Insert Count 10, Required Insert Count 201,
                // Delta Base 0, Base 201.
       "80"));  // Emit dynamic table entry with relative index 0.
@@ -678,31 +676,31 @@
 
 TEST_P(QpackDecoderTest, NonZeroRequiredInsertCountButNoDynamicEntries) {
   // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
   // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
 
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
   EXPECT_CALL(handler_,
               OnDecodingErrorDetected(Eq("Required Insert Count too large.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0200"   // Required Insert Count is 1.
       "d1"));  // But the only instruction references the static table.
 }
 
 TEST_P(QpackDecoderTest, AddressEntryNotAllowedByRequiredInsertCount) {
   // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
   // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
 
   EXPECT_CALL(
       handler_,
       OnDecodingErrorDetected(
           Eq("Absolute Index must be smaller than Required Insert Count.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0201"   // Required Insert Count 1 and Delta Base 1.
                // Base is 1 + 1 = 2.
       "80"));  // Indexed Header Field instruction addressing dynamic table
@@ -714,7 +712,7 @@
       OnDecodingErrorDetected(
           Eq("Absolute Index must be smaller than Required Insert Count.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0201"     // Required Insert Count 1 and Delta Base 1.
                  // Base is 1 + 1 = 2.
       "4000"));  // Literal Header Field with Name Reference instruction
@@ -727,7 +725,7 @@
       OnDecodingErrorDetected(
           Eq("Absolute Index must be smaller than Required Insert Count.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0200"   // Required Insert Count 1 and Delta Base 0.
                // Base is 1 + 0 = 1.
       "10"));  // Indexed Header Field with Post-Base Index instruction
@@ -740,7 +738,7 @@
       OnDecodingErrorDetected(
           Eq("Absolute Index must be smaller than Required Insert Count.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0200"     // Required Insert Count 1 and Delta Base 0.
                  // Base is 1 + 0 = 1.
       "0000"));  // Literal Header Field with Post-Base Name Reference
@@ -751,19 +749,19 @@
 
 TEST_P(QpackDecoderTest, PromisedRequiredInsertCountLargerThanActual) {
   // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
   // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
   // Duplicate entry twice so that decoding of header blocks with Required
   // Insert Count not exceeding 3 is not blocked.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("00"));
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("00"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("00"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("00"));
 
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
   EXPECT_CALL(handler_,
               OnDecodingErrorDetected(Eq("Required Insert Count too large.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0300"   // Required Insert Count 2 and Delta Base 0.
                // Base is 2 + 0 = 2.
       "81"));  // Indexed Header Field instruction addressing dynamic table
@@ -775,7 +773,7 @@
   EXPECT_CALL(handler_,
               OnDecodingErrorDetected(Eq("Required Insert Count too large.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0300"     // Required Insert Count 2 and Delta Base 0.
                  // Base is 2 + 0 = 2.
       "4100"));  // Literal Header Field with Name Reference instruction
@@ -787,7 +785,7 @@
   EXPECT_CALL(handler_,
               OnDecodingErrorDetected(Eq("Required Insert Count too large.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0481"   // Required Insert Count 3 and Delta Base 1 with sign bit set.
                // Base is 3 - 1 - 1 = 1.
       "10"));  // Indexed Header Field with Post-Base Index instruction
@@ -799,7 +797,7 @@
   EXPECT_CALL(handler_,
               OnDecodingErrorDetected(Eq("Required Insert Count too large.")));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0481"     // Required Insert Count 3 and Delta Base 1 with sign bit set.
                  // Base is 3 - 1 - 1 = 1.
       "0000"));  // Literal Header Field with Post-Base Name Reference
@@ -809,7 +807,7 @@
 }
 
 TEST_P(QpackDecoderTest, BlockedDecoding) {
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0200"   // Required Insert Count 1 and Delta Base 0.
                // Base is 1 + 0 = 1.
       "80"));  // Indexed Header Field instruction addressing dynamic table
@@ -821,14 +819,14 @@
               WriteStreamData(Eq(kHeaderAcknowledgement)));
 
   // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
   // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
 }
 
 TEST_P(QpackDecoderTest, BlockedDecodingUnblockedBeforeEndOfHeaderBlock) {
   StartDecoding();
-  DecodeData(quiche::QuicheTextUtils::HexDecode(
+  DecodeData(absl::HexStringToBytes(
       "0200"   // Required Insert Count 1 and Delta Base 0.
                // Base is 1 + 0 = 1.
       "80"     // Indexed Header Field instruction addressing dynamic table
@@ -836,7 +834,7 @@
       "d1"));  // Static table entry with index 17.
 
   // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
 
   // Add literal entry with name "foo" and value "bar".  Decoding is now
   // unblocked because dynamic table Insert Count reached the Required Insert
@@ -844,14 +842,14 @@
   // the already consumed part of the header block.
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":method"), Eq("GET")));
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
   Mock::VerifyAndClearExpectations(&handler_);
 
   // Rest of header block is processed by QpackProgressiveDecoder
   // in the unblocked state.
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq(":scheme"), Eq("https")));
-  DecodeData(quiche::QuicheTextUtils::HexDecode(
+  DecodeData(absl::HexStringToBytes(
       "80"     // Indexed Header Field instruction addressing dynamic table
                // entry with relative index 0, absolute index 0.
       "d7"));  // Static table entry with index 23.
@@ -867,7 +865,7 @@
 TEST_P(QpackDecoderTest,
        BlockedDecodingUnblockedAndErrorBeforeEndOfHeaderBlock) {
   StartDecoding();
-  DecodeData(quiche::QuicheTextUtils::HexDecode(
+  DecodeData(absl::HexStringToBytes(
       "0200"   // Required Insert Count 1 and Delta Base 0.
                // Base is 1 + 0 = 1.
       "80"     // Indexed Header Field instruction addressing dynamic table
@@ -875,7 +873,7 @@
       "81"));  // Relative index 1 is equal to Base, therefore invalid.
 
   // Set dynamic table capacity to 1024.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3fe107"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3fe107"));
 
   // Add literal entry with name "foo" and value "bar".  Decoding is now
   // unblocked because dynamic table Insert Count reached the Required Insert
@@ -883,7 +881,7 @@
   // the already consumed part of the header block.
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
   EXPECT_CALL(handler_, OnDecodingErrorDetected(Eq("Invalid relative index.")));
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
 }
 
 // Make sure that Required Insert Count is compared to Insert Count,
@@ -891,19 +889,19 @@
 TEST_P(QpackDecoderTest, BlockedDecodingAndEvictedEntries) {
   // Update dynamic table capacity to 128.
   // At most three non-empty entries fit in the dynamic table.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("3f61"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("3f61"));
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0700"   // Required Insert Count 6 and Delta Base 0.
                // Base is 6 + 0 = 6.
       "80"));  // Indexed Header Field instruction addressing dynamic table
                // entry with relative index 0, absolute index 5.
 
   // Add literal entry with name "foo" and value "bar".
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e703626172"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e703626172"));
 
   // Duplicate entry four times.  This evicts the first two instances.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("00000000"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("00000000"));
 
   EXPECT_CALL(handler_, OnHeaderDecoded(Eq("foo"), Eq("baz")));
   EXPECT_CALL(handler_, OnDecodingCompleted());
@@ -912,13 +910,13 @@
 
   // Add literal entry with name "foo" and value "bar".
   // Insert Count is now 6, reaching Required Insert Count of the header block.
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode("6294e70362617a"));
+  DecodeEncoderStreamData(absl::HexStringToBytes("6294e70362617a"));
 }
 
 TEST_P(QpackDecoderTest, TooManyBlockedStreams) {
   // Required Insert Count 1 and Delta Base 0.
   // Without any dynamic table entries received, decoding is blocked.
-  std::string data = quiche::QuicheTextUtils::HexDecode("0200");
+  std::string data = absl::HexStringToBytes("0200");
 
   auto progressive_decoder1 = CreateProgressiveDecoder(/* stream_id = */ 1);
   progressive_decoder1->Decode(data);
@@ -931,7 +929,7 @@
 }
 
 TEST_P(QpackDecoderTest, InsertCountIncrement) {
-  DecodeEncoderStreamData(quiche::QuicheTextUtils::HexDecode(
+  DecodeEncoderStreamData(absl::HexStringToBytes(
       "3fe107"          // Set dynamic table capacity to 1024.
       "6294e703626172"  // Add literal entry with name "foo" and value "bar".
       "00"));           // Duplicate entry.
@@ -943,11 +941,11 @@
   // Known Insert Count to one.  Decoder should send an Insert Count Increment
   // instruction with increment of one to update Known Insert Count to two.
   EXPECT_CALL(decoder_stream_sender_delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode(
+              WriteStreamData(Eq(absl::HexStringToBytes(
                   "81"       // Header Acknowledgement on stream 1
                   "01"))));  // Insert Count Increment with increment of one
 
-  DecodeHeaderBlock(quiche::QuicheTextUtils::HexDecode(
+  DecodeHeaderBlock(absl::HexStringToBytes(
       "0200"   // Required Insert Count 1 and Delta Base 0.
                // Base is 1 + 0 = 1.
       "80"));  // Dynamic table entry with relative index 0, absolute index 0.
diff --git a/quic/core/qpack/qpack_encoder_stream_receiver_test.cc b/quic/core/qpack/qpack_encoder_stream_receiver_test.cc
index 235bd79..31bea89 100644
--- a/quic/core/qpack/qpack_encoder_stream_receiver_test.cc
+++ b/quic/core/qpack/qpack_encoder_stream_receiver_test.cc
@@ -4,6 +4,7 @@
 
 #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h"
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
@@ -60,7 +61,7 @@
   EXPECT_CALL(*delegate(),
               OnInsertWithNameReference(false, 42, Eq(std::string(127, 'Z'))));
 
-  Decode(quiche::QuicheTextUtils::HexDecode(
+  Decode(absl::HexStringToBytes(
       "c500"
       "c28294e7"
       "bf4a03626172"
@@ -75,7 +76,7 @@
               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
                               Eq("Encoded integer too large.")));
 
-  Decode(quiche::QuicheTextUtils::HexDecode("bfffffffffffffffffffffff"));
+  Decode(absl::HexStringToBytes("bfffffffffffffffffffffff"));
 }
 
 TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceValueTooLong) {
@@ -83,7 +84,7 @@
               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
                               Eq("Encoded integer too large.")));
 
-  Decode(quiche::QuicheTextUtils::HexDecode("c57fffffffffffffffffffff"));
+  Decode(absl::HexStringToBytes("c57fffffffffffffffffffff"));
 }
 
 TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReference) {
@@ -99,7 +100,7 @@
               OnInsertWithoutNameReference(Eq(std::string(31, 'Z')),
                                            Eq(std::string(127, 'Z'))));
 
-  Decode(quiche::QuicheTextUtils::HexDecode(
+  Decode(absl::HexStringToBytes(
       "4000"
       "4362617203626172"
       "6294e78294e7"
@@ -117,7 +118,7 @@
               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
                               Eq("Encoded integer too large.")));
 
-  Decode(quiche::QuicheTextUtils::HexDecode("5fffffffffffffffffffff"));
+  Decode(absl::HexStringToBytes("5fffffffffffffffffffff"));
 }
 
 // Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
@@ -127,7 +128,7 @@
               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
                               Eq("String literal too long.")));
 
-  Decode(quiche::QuicheTextUtils::HexDecode("5fffff7f"));
+  Decode(absl::HexStringToBytes("5fffff7f"));
 }
 
 // Value Length value is too large for varint decoder to decode.
@@ -137,7 +138,7 @@
               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
                               Eq("Encoded integer too large.")));
 
-  Decode(quiche::QuicheTextUtils::HexDecode("436261727fffffffffffffffffffff"));
+  Decode(absl::HexStringToBytes("436261727fffffffffffffffffffff"));
 }
 
 // Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
@@ -147,7 +148,7 @@
               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
                               Eq("String literal too long.")));
 
-  Decode(quiche::QuicheTextUtils::HexDecode("436261727fffff7f"));
+  Decode(absl::HexStringToBytes("436261727fffff7f"));
 }
 
 TEST_F(QpackEncoderStreamReceiverTest, Duplicate) {
@@ -156,7 +157,7 @@
   // Large index requires two extension bytes.
   EXPECT_CALL(*delegate(), OnDuplicate(500));
 
-  Decode(quiche::QuicheTextUtils::HexDecode("111fd503"));
+  Decode(absl::HexStringToBytes("111fd503"));
 }
 
 TEST_F(QpackEncoderStreamReceiverTest, DuplicateIndexTooLarge) {
@@ -164,7 +165,7 @@
               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
                               Eq("Encoded integer too large.")));
 
-  Decode(quiche::QuicheTextUtils::HexDecode("1fffffffffffffffffffff"));
+  Decode(absl::HexStringToBytes("1fffffffffffffffffffff"));
 }
 
 TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacity) {
@@ -173,7 +174,7 @@
   // Large capacity requires two extension bytes.
   EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(500));
 
-  Decode(quiche::QuicheTextUtils::HexDecode("313fd503"));
+  Decode(absl::HexStringToBytes("313fd503"));
 }
 
 TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacityTooLarge) {
@@ -181,7 +182,7 @@
               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
                               Eq("Encoded integer too large.")));
 
-  Decode(quiche::QuicheTextUtils::HexDecode("3fffffffffffffffffffff"));
+  Decode(absl::HexStringToBytes("3fffffffffffffffffffff"));
 }
 
 TEST_F(QpackEncoderStreamReceiverTest, InvalidHuffmanEncoding) {
@@ -189,7 +190,7 @@
               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR,
                               Eq("Error in Huffman-encoded string.")));
 
-  Decode(quiche::QuicheTextUtils::HexDecode("c281ff"));
+  Decode(absl::HexStringToBytes("c281ff"));
 }
 
 }  // namespace
diff --git a/quic/core/qpack/qpack_encoder_stream_sender_test.cc b/quic/core/qpack/qpack_encoder_stream_sender_test.cc
index ea45acc..0813819 100644
--- a/quic/core/qpack/qpack_encoder_stream_sender_test.cc
+++ b/quic/core/qpack/qpack_encoder_stream_sender_test.cc
@@ -4,6 +4,7 @@
 
 #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h"
 
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
 #include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
@@ -30,22 +31,21 @@
   EXPECT_EQ(0u, stream_.BufferedByteCount());
 
   // Static, index fits in prefix, empty value.
-  std::string expected_encoded_data =
-      quiche::QuicheTextUtils::HexDecode("c500");
+  std::string expected_encoded_data = absl::HexStringToBytes("c500");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
   stream_.SendInsertWithNameReference(true, 5, "");
   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
   stream_.Flush();
 
   // Static, index fits in prefix, Huffman encoded value.
-  expected_encoded_data = quiche::QuicheTextUtils::HexDecode("c28294e7");
+  expected_encoded_data = absl::HexStringToBytes("c28294e7");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
   stream_.SendInsertWithNameReference(true, 2, "foo");
   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
   stream_.Flush();
 
   // Not static, index does not fit in prefix, not Huffman encoded value.
-  expected_encoded_data = quiche::QuicheTextUtils::HexDecode("bf4a03626172");
+  expected_encoded_data = absl::HexStringToBytes("bf4a03626172");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
   stream_.SendInsertWithNameReference(false, 137, "bar");
   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
@@ -53,7 +53,7 @@
 
   // Value length does not fit in prefix.
   // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
-  expected_encoded_data = quiche::QuicheTextUtils::HexDecode(
+  expected_encoded_data = absl::HexStringToBytes(
       "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
@@ -68,23 +68,21 @@
   EXPECT_EQ(0u, stream_.BufferedByteCount());
 
   // Empty name and value.
-  std::string expected_encoded_data =
-      quiche::QuicheTextUtils::HexDecode("4000");
+  std::string expected_encoded_data = absl::HexStringToBytes("4000");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
   stream_.SendInsertWithoutNameReference("", "");
   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
   stream_.Flush();
 
   // Huffman encoded short strings.
-  expected_encoded_data = quiche::QuicheTextUtils::HexDecode("6294e78294e7");
+  expected_encoded_data = absl::HexStringToBytes("6294e78294e7");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
   stream_.SendInsertWithoutNameReference("foo", "foo");
   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
   stream_.Flush();
 
   // Not Huffman encoded short strings.
-  expected_encoded_data =
-      quiche::QuicheTextUtils::HexDecode("4362617203626172");
+  expected_encoded_data = absl::HexStringToBytes("4362617203626172");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
   stream_.SendInsertWithoutNameReference("bar", "bar");
   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
@@ -92,7 +90,7 @@
 
   // Not Huffman encoded long strings; length does not fit on prefix.
   // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
-  expected_encoded_data = quiche::QuicheTextUtils::HexDecode(
+  expected_encoded_data = absl::HexStringToBytes(
       "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f"
       "005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
@@ -109,14 +107,14 @@
   EXPECT_EQ(0u, stream_.BufferedByteCount());
 
   // Small index fits in prefix.
-  std::string expected_encoded_data = quiche::QuicheTextUtils::HexDecode("11");
+  std::string expected_encoded_data = absl::HexStringToBytes("11");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
   stream_.SendDuplicate(17);
   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
   stream_.Flush();
 
   // Large index requires two extension bytes.
-  expected_encoded_data = quiche::QuicheTextUtils::HexDecode("1fd503");
+  expected_encoded_data = absl::HexStringToBytes("1fd503");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
   stream_.SendDuplicate(500);
   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
@@ -127,7 +125,7 @@
   EXPECT_EQ(0u, stream_.BufferedByteCount());
 
   // Small capacity fits in prefix.
-  std::string expected_encoded_data = quiche::QuicheTextUtils::HexDecode("31");
+  std::string expected_encoded_data = absl::HexStringToBytes("31");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
   stream_.SendSetDynamicTableCapacity(17);
   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
@@ -135,7 +133,7 @@
   EXPECT_EQ(0u, stream_.BufferedByteCount());
 
   // Large capacity requires two extension bytes.
-  expected_encoded_data = quiche::QuicheTextUtils::HexDecode("3fd503");
+  expected_encoded_data = absl::HexStringToBytes("3fd503");
   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
   stream_.SendSetDynamicTableCapacity(500);
   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
@@ -157,7 +155,7 @@
   // Duplicate entry.
   stream_.SendDuplicate(17);
 
-  std::string expected_encoded_data = quiche::QuicheTextUtils::HexDecode(
+  std::string expected_encoded_data = absl::HexStringToBytes(
       "c500"          // Insert entry with static name reference.
       "c28294e7"      // Insert entry with static name reference.
       "6294e78294e7"  // Insert literal entry.
diff --git a/quic/core/qpack/qpack_encoder_test.cc b/quic/core/qpack/qpack_encoder_test.cc
index 9bc377e..08c6123 100644
--- a/quic/core/qpack/qpack_encoder_test.cc
+++ b/quic/core/qpack/qpack_encoder_test.cc
@@ -7,6 +7,7 @@
 #include <limits>
 #include <string>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -51,7 +52,7 @@
   spdy::Http2HeaderBlock header_list;
   std::string output = Encode(header_list);
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0000"), output);
+  EXPECT_EQ(absl::HexStringToBytes("0000"), output);
 }
 
 TEST_F(QpackEncoderTest, EmptyName) {
@@ -59,7 +60,7 @@
   header_list[""] = "foo";
   std::string output = Encode(header_list);
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0000208294e7"), output);
+  EXPECT_EQ(absl::HexStringToBytes("0000208294e7"), output);
 }
 
 TEST_F(QpackEncoderTest, EmptyValue) {
@@ -67,7 +68,7 @@
   header_list["foo"] = "";
   std::string output = Encode(header_list);
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("00002a94e700"), output);
+  EXPECT_EQ(absl::HexStringToBytes("00002a94e700"), output);
 }
 
 TEST_F(QpackEncoderTest, EmptyNameAndValue) {
@@ -75,7 +76,7 @@
   header_list[""] = "";
   std::string output = Encode(header_list);
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("00002000"), output);
+  EXPECT_EQ(absl::HexStringToBytes("00002000"), output);
 }
 
 TEST_F(QpackEncoderTest, Simple) {
@@ -83,7 +84,7 @@
   header_list["foo"] = "bar";
   std::string output = Encode(header_list);
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("00002a94e703626172"), output);
+  EXPECT_EQ(absl::HexStringToBytes("00002a94e703626172"), output);
 }
 
 TEST_F(QpackEncoderTest, Multiple) {
@@ -94,7 +95,7 @@
   std::string output = Encode(header_list);
 
   EXPECT_EQ(
-      quiche::QuicheTextUtils::HexDecode(
+      absl::HexStringToBytes(
           "0000"                // prefix
           "2a94e703626172"      // foo: bar
           "27005a5a5a5a5a5a5a"  // 7 octet long header name, the smallest number
@@ -116,7 +117,7 @@
     header_list["location"] = "";
 
     std::string output = Encode(header_list);
-    EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0000d1dfcc"), output);
+    EXPECT_EQ(absl::HexStringToBytes("0000d1dfcc"), output);
   }
   {
     spdy::Http2HeaderBlock header_list;
@@ -125,9 +126,8 @@
     header_list["location"] = "foo";
 
     std::string output = Encode(header_list);
-    EXPECT_EQ(
-        quiche::QuicheTextUtils::HexDecode("0000d45f108621e9aec2a11f5c8294e7"),
-        output);
+    EXPECT_EQ(absl::HexStringToBytes("0000d45f108621e9aec2a11f5c8294e7"),
+              output);
   }
   {
     spdy::Http2HeaderBlock header_list;
@@ -135,8 +135,7 @@
     header_list["accept-encoding"] = "";
 
     std::string output = Encode(header_list);
-    EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("00005f000554524143455f1000"),
-              output);
+    EXPECT_EQ(absl::HexStringToBytes("00005f000554524143455f1000"), output);
   }
 }
 
@@ -151,7 +150,7 @@
   QpackEncoder encoder(&decoder_stream_error_delegate_);
   encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate_);
   encoder.decoder_stream_receiver()->Decode(
-      quiche::QuicheTextUtils::HexDecode("ffffffffffffffffffffff"));
+      absl::HexStringToBytes("ffffffffffffffffffffff"));
 }
 
 TEST_F(QpackEncoderTest, SplitAlongNullCharacter) {
@@ -159,11 +158,11 @@
   header_list["foo"] = absl::string_view("bar\0bar\0baz", 11);
   std::string output = Encode(header_list);
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0000"            // prefix
-                                               "2a94e703626172"  // foo: bar
-                                               "2a94e703626172"  // foo: bar
-                                               "2a94e70362617a"  // foo: baz
-                                               ),
+  EXPECT_EQ(absl::HexStringToBytes("0000"            // prefix
+                                   "2a94e703626172"  // foo: bar
+                                   "2a94e703626172"  // foo: bar
+                                   "2a94e70362617a"  // foo: baz
+                                   ),
             output);
 }
 
@@ -241,10 +240,9 @@
   header_list["cookie"] = "baz";              // name matches static entry
 
   // Set Dynamic Table Capacity instruction.
-  std::string set_dyanamic_table_capacity =
-      quiche::QuicheTextUtils::HexDecode("3fe11f");
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
   // Insert three entries into the dynamic table.
-  std::string insert_entries = quiche::QuicheTextUtils::HexDecode(
+  std::string insert_entries = absl::HexStringToBytes(
       "62"          // insert without name reference
       "94e7"        // Huffman-encoded name "foo"
       "03626172"    // value "bar"
@@ -256,7 +254,7 @@
               WriteStreamData(Eq(quiche::QuicheStrCat(
                   set_dyanamic_table_capacity, insert_entries))));
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode(
+  EXPECT_EQ(absl::HexStringToBytes(
                 "0400"      // prefix
                 "828180"),  // dynamic entries with relative index 0, 1, and 2
             Encode(header_list));
@@ -278,10 +276,9 @@
   header_list["bar"] = "baz";                 // no match
 
   // Set Dynamic Table Capacity instruction.
-  std::string set_dyanamic_table_capacity =
-      quiche::QuicheTextUtils::HexDecode("3f07");
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3f07");
   // Insert one entry into the dynamic table.
-  std::string insert_entry = quiche::QuicheTextUtils::HexDecode(
+  std::string insert_entry = absl::HexStringToBytes(
       "62"          // insert without name reference
       "94e7"        // Huffman-encoded name "foo"
       "03626172");  // value "bar"
@@ -289,15 +286,14 @@
               WriteStreamData(Eq(quiche::QuicheStrCat(
                   set_dyanamic_table_capacity, insert_entry))));
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode(
-                "0200"        // prefix
-                "80"          // dynamic entry 0
-                "40"          // reference to dynamic entry 0 name
-                "0362617a"    // with literal value "baz"
-                "55"          // reference to static entry 5 name
-                "0362617a"    // with literal value "baz"
-                "23626172"    // literal name "bar"
-                "0362617a"),  // with literal value "baz"
+  EXPECT_EQ(absl::HexStringToBytes("0200"  // prefix
+                                   "80"    // dynamic entry 0
+                                   "40"    // reference to dynamic entry 0 name
+                                   "0362617a"  // with literal value "baz"
+                                   "55"  // reference to static entry 5 name
+                                   "0362617a"    // with literal value "baz"
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
             Encode(header_list));
 
   EXPECT_EQ(insert_entry.size(), encoder_stream_sent_byte_count_);
@@ -312,10 +308,9 @@
   header_list1["foo"] = "bar";
 
   // Set Dynamic Table Capacity instruction.
-  std::string set_dyanamic_table_capacity =
-      quiche::QuicheTextUtils::HexDecode("3fe11f");
+  std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
   // Insert one entry into the dynamic table.
-  std::string insert_entry1 = quiche::QuicheTextUtils::HexDecode(
+  std::string insert_entry1 = absl::HexStringToBytes(
       "62"          // insert without name reference
       "94e7"        // Huffman-encoded name "foo"
       "03626172");  // value "bar"
@@ -323,8 +318,8 @@
               WriteStreamData(Eq(quiche::QuicheStrCat(
                   set_dyanamic_table_capacity, insert_entry1))));
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0200"  // prefix
-                                               "80"),  // dynamic entry 0
+  EXPECT_EQ(absl::HexStringToBytes("0200"  // prefix
+                                   "80"),  // dynamic entry 0
             encoder_.EncodeHeaderList(/* stream_id = */ 1, header_list1,
                                       &encoder_stream_sent_byte_count_));
   EXPECT_EQ(insert_entry1.size(), encoder_stream_sent_byte_count_);
@@ -337,16 +332,15 @@
   header_list2["cookie"] = "baz";              // name matches static entry
   header_list2["bar"] = "baz";                 // no match
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode(
-                "0000"        // prefix
-                "2a94e7"      // literal name "foo"
-                "03626172"    // with literal value "bar"
-                "2a94e7"      // literal name "foo"
-                "0362617a"    // with literal value "baz"
-                "55"          // name of static entry 5
-                "0362617a"    // with literal value "baz"
-                "23626172"    // literal name "bar"
-                "0362617a"),  // with literal value "baz"
+  EXPECT_EQ(absl::HexStringToBytes("0000"        // prefix
+                                   "2a94e7"      // literal name "foo"
+                                   "03626172"    // with literal value "bar"
+                                   "2a94e7"      // literal name "foo"
+                                   "0362617a"    // with literal value "baz"
+                                   "55"          // name of static entry 5
+                                   "0362617a"    // with literal value "baz"
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
             encoder_.EncodeHeaderList(/* stream_id = */ 2, header_list2,
                                       &encoder_stream_sent_byte_count_));
   EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
@@ -356,7 +350,7 @@
   encoder_.OnInsertCountIncrement(1);
 
   // Insert three entries into the dynamic table.
-  std::string insert_entries = quiche::QuicheTextUtils::HexDecode(
+  std::string insert_entries = absl::HexStringToBytes(
       "80"          // insert with name reference, dynamic index 0
       "0362617a"    // value "baz"
       "c5"          // insert with name reference, static index 5
@@ -367,23 +361,22 @@
   EXPECT_CALL(encoder_stream_sender_delegate_,
               WriteStreamData(Eq(insert_entries)));
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0500"        // prefix
-                                               "83828180"),  // dynamic entries
+  EXPECT_EQ(absl::HexStringToBytes("0500"        // prefix
+                                   "83828180"),  // dynamic entries
             encoder_.EncodeHeaderList(/* stream_id = */ 3, header_list2,
                                       &encoder_stream_sent_byte_count_));
   EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
 
   // Stream 3 is blocked.  Stream 4 is not allowed to block, but it can
   // reference already acknowledged dynamic entry 0.
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode(
-                "0200"        // prefix
-                "80"          // dynamic entry 0
-                "2a94e7"      // literal name "foo"
-                "0362617a"    // with literal value "baz"
-                "2c21cfd4c5"  // literal name "cookie"
-                "0362617a"    // with literal value "baz"
-                "23626172"    // literal name "bar"
-                "0362617a"),  // with literal value "baz"
+  EXPECT_EQ(absl::HexStringToBytes("0200"        // prefix
+                                   "80"          // dynamic entry 0
+                                   "2a94e7"      // literal name "foo"
+                                   "0362617a"    // with literal value "baz"
+                                   "2c21cfd4c5"  // literal name "cookie"
+                                   "0362617a"    // with literal value "baz"
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
             encoder_.EncodeHeaderList(/* stream_id = */ 4, header_list2,
                                       &encoder_stream_sent_byte_count_));
   EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
@@ -394,11 +387,10 @@
 
   // Stream 5 is not allowed to block, but it can reference already acknowledged
   // dynamic entries 0, 1, and 2.
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode(
-                "0400"        // prefix
-                "828180"      // dynamic entries
-                "23626172"    // literal name "bar"
-                "0362617a"),  // with literal value "baz"
+  EXPECT_EQ(absl::HexStringToBytes("0400"        // prefix
+                                   "828180"      // dynamic entries
+                                   "23626172"    // literal name "bar"
+                                   "0362617a"),  // with literal value "baz"
             encoder_.EncodeHeaderList(/* stream_id = */ 5, header_list2,
                                       &encoder_stream_sent_byte_count_));
   EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
@@ -407,8 +399,8 @@
   // Stream 3 is not blocked any longer.
   encoder_.OnHeaderAcknowledgement(3);
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode("0500"        // prefix
-                                               "83828180"),  // dynamic entries
+  EXPECT_EQ(absl::HexStringToBytes("0500"        // prefix
+                                   "83828180"),  // dynamic entries
             encoder_.EncodeHeaderList(/* stream_id = */ 6, header_list2,
                                       &encoder_stream_sent_byte_count_));
   EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
@@ -443,9 +435,8 @@
   // dynamic table.
   EXPECT_CALL(encoder_stream_sender_delegate_, WriteStreamData(_));
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode(
-                "0b00"                    // prefix
-                "89888786858483828180"),  // dynamic entries
+  EXPECT_EQ(absl::HexStringToBytes("0b00"                    // prefix
+                                   "89888786858483828180"),  // dynamic entries
             Encode(header_list1));
 
   // Entry is identical to oldest one, which is draining.  It will be
@@ -455,11 +446,10 @@
 
   // Duplicate oldest entry.
   EXPECT_CALL(encoder_stream_sender_delegate_,
-              WriteStreamData(Eq(quiche::QuicheTextUtils::HexDecode("09"))));
+              WriteStreamData(Eq(absl::HexStringToBytes("09"))));
 
-  EXPECT_EQ(quiche::QuicheTextUtils::HexDecode(
-                "0c00"  // prefix
-                "80"),  // most recent dynamic table entry
+  EXPECT_EQ(absl::HexStringToBytes("0c00"  // prefix
+                                   "80"),  // most recent dynamic table entry
             Encode(header_list2));
 
   spdy::Http2HeaderBlock header_list3;
@@ -470,13 +460,12 @@
   // no room to insert new entry, it will be encoded with string literals.
   header_list3.AppendValueOrAddHeader("two", "bar");
 
-  EXPECT_EQ(
-      quiche::QuicheTextUtils::HexDecode("0000"        // prefix
-                                         "2374776f"    // literal name "two"
-                                         "8294e7"      // literal value "foo"
-                                         "2374776f"    // literal name "two"
-                                         "03626172"),  // literal value "bar"
-      Encode(header_list3));
+  EXPECT_EQ(absl::HexStringToBytes("0000"        // prefix
+                                   "2374776f"    // literal name "two"
+                                   "8294e7"      // literal value "foo"
+                                   "2374776f"    // literal name "two"
+                                   "03626172"),  // literal value "bar"
+            Encode(header_list3));
 }
 
 TEST_F(QpackEncoderTest, DynamicTableCapacityLessThanMaximum) {
diff --git a/quic/core/qpack/qpack_instruction_decoder_test.cc b/quic/core/qpack/qpack_instruction_decoder_test.cc
index ac7b369..52ec38b 100644
--- a/quic/core/qpack/qpack_instruction_decoder_test.cc
+++ b/quic/core/qpack/qpack_instruction_decoder_test.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
@@ -130,14 +131,14 @@
 
 TEST_P(QpackInstructionDecoderTest, SBitAndVarint2) {
   EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
-  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("7f01ff65"));
+  DecodeInstruction(absl::HexStringToBytes("7f01ff65"));
 
   EXPECT_TRUE(decoder_->s_bit());
   EXPECT_EQ(64u, decoder_->varint());
   EXPECT_EQ(356u, decoder_->varint2());
 
   EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
-  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("05c8"));
+  DecodeInstruction(absl::HexStringToBytes("05c8"));
 
   EXPECT_FALSE(decoder_->s_bit());
   EXPECT_EQ(5u, decoder_->varint());
@@ -146,19 +147,19 @@
 
 TEST_P(QpackInstructionDecoderTest, NameAndValue) {
   EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
-  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("83666f6f03626172"));
+  DecodeInstruction(absl::HexStringToBytes("83666f6f03626172"));
 
   EXPECT_EQ("foo", decoder_->name());
   EXPECT_EQ("bar", decoder_->value());
 
   EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
-  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("8000"));
+  DecodeInstruction(absl::HexStringToBytes("8000"));
 
   EXPECT_EQ("", decoder_->name());
   EXPECT_EQ("", decoder_->value());
 
   EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
-  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("c294e7838c767f"));
+  DecodeInstruction(absl::HexStringToBytes("c294e7838c767f"));
 
   EXPECT_EQ("foo", decoder_->name());
   EXPECT_EQ("bar", decoder_->value());
@@ -169,7 +170,7 @@
               OnInstructionDecodingError(
                   QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR,
                   Eq("Error in Huffman-encoded string.")));
-  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("c1ff"));
+  DecodeInstruction(absl::HexStringToBytes("c1ff"));
 }
 
 TEST_P(QpackInstructionDecoderTest, InvalidVarintEncoding) {
@@ -177,8 +178,7 @@
               OnInstructionDecodingError(
                   QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE,
                   Eq("Encoded integer too large.")));
-  DecodeInstruction(
-      quiche::QuicheTextUtils::HexDecode("ffffffffffffffffffffff"));
+  DecodeInstruction(absl::HexStringToBytes("ffffffffffffffffffffff"));
 }
 
 TEST_P(QpackInstructionDecoderTest, StringLiteralTooLong) {
@@ -186,7 +186,7 @@
               OnInstructionDecodingError(
                   QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG,
                   Eq("String literal too long.")));
-  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("bfffff7f"));
+  DecodeInstruction(absl::HexStringToBytes("bfffff7f"));
 }
 
 TEST_P(QpackInstructionDecoderTest, DelegateSignalsError) {
@@ -206,8 +206,8 @@
         return false;
       }));
 
-  EXPECT_FALSE(decoder_->Decode(
-      quiche::QuicheTextUtils::HexDecode("01000200030004000500")));
+  EXPECT_FALSE(
+      decoder_->Decode(absl::HexStringToBytes("01000200030004000500")));
 }
 
 // QpackInstructionDecoder must not crash if it is destroyed from a
@@ -219,7 +219,7 @@
         decoder_.reset();
         return false;
       }));
-  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("0100"));
+  DecodeInstruction(absl::HexStringToBytes("0100"));
 }
 
 }  // namespace
diff --git a/quic/core/qpack/qpack_instruction_encoder_test.cc b/quic/core/qpack/qpack_instruction_encoder_test.cc
index 66a6c42..893bc50 100644
--- a/quic/core/qpack/qpack_instruction_encoder_test.cc
+++ b/quic/core/qpack/qpack_instruction_encoder_test.cc
@@ -4,6 +4,7 @@
 
 #include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h"
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -65,8 +66,7 @@
   bool EncodedSegmentMatches(absl::string_view hex_encoded_expected_substring) {
     auto recently_encoded =
         absl::string_view(output_).substr(verified_position_);
-    auto expected =
-        quiche::QuicheTextUtils::HexDecode(hex_encoded_expected_substring);
+    auto expected = absl::HexStringToBytes(hex_encoded_expected_substring);
     verified_position_ = output_.size();
     return recently_encoded == expected;
   }
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 1dc7f94..f493598 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -15,6 +15,7 @@
 #include <string>
 #include <utility>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
 #include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h"
@@ -939,21 +940,20 @@
       QUIC_DLOG(ERROR) << "Ignoring RETRY with original connection ID "
                        << original_connection_id << " not matching expected "
                        << server_connection_id_ << " token "
-                       << quiche::QuicheTextUtils::HexEncode(retry_token);
+                       << absl::BytesToHexString(retry_token);
       return;
     }
   }
   if (drop_incoming_retry_packets_) {
     QUIC_DLOG(ERROR) << "Ignoring RETRY with token "
-                     << quiche::QuicheTextUtils::HexEncode(retry_token);
+                     << absl::BytesToHexString(retry_token);
     return;
   }
   drop_incoming_retry_packets_ = true;
   stats_.retry_packet_processed = true;
   QUIC_DLOG(INFO) << "Received RETRY, replacing connection ID "
                   << server_connection_id_ << " with " << new_connection_id
-                  << ", received token "
-                  << quiche::QuicheTextUtils::HexEncode(retry_token);
+                  << ", received token " << absl::BytesToHexString(retry_token);
   if (!original_destination_connection_id_.has_value()) {
     original_destination_connection_id_ = server_connection_id_;
   }
diff --git a/quic/core/quic_connection_id.cc b/quic/core/quic_connection_id.cc
index 57e57c5..e682ee3 100644
--- a/quic/core/quic_connection_id.cc
+++ b/quic/core/quic_connection_id.cc
@@ -10,6 +10,7 @@
 #include <iomanip>
 #include <string>
 
+#include "absl/strings/escaping.h"
 #include "third_party/boringssl/src/include/openssl/siphash.h"
 #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
 #include "net/third_party/quiche/src/quic/core/quic_types.h"
@@ -144,7 +145,7 @@
   if (IsEmpty()) {
     return std::string("0");
   }
-  return quiche::QuicheTextUtils::HexEncode(data(), length_);
+  return absl::BytesToHexString(absl::string_view(data(), length_));
 }
 
 std::ostream& operator<<(std::ostream& os, const QuicConnectionId& v) {
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 66765b0..58bf909 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -14,6 +14,7 @@
 #include "absl/base/attributes.h"
 #include "absl/base/macros.h"
 #include "absl/base/optimization.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/numbers.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h"
@@ -1648,8 +1649,8 @@
                     << "Failed to parse received coalesced header of length "
                     << coalesced_data_length
                     << " with error: " << detailed_error_ << ": "
-                    << quiche::QuicheTextUtils::HexEncode(coalesced_data,
-                                                          coalesced_data_length)
+                    << absl::BytesToHexString(absl::string_view(
+                           coalesced_data, coalesced_data_length))
                     << " previous header was " << header;
     return;
   }
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index aa7fa8b..ba9a70e 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -13,6 +13,7 @@
 #include <vector>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
@@ -768,10 +769,8 @@
             retry_token_length, length_length);
     if (associated_data != decrypter_->associated_data_) {
       QUIC_LOG(ERROR) << "Decrypted incorrect associated data.  expected "
-                      << quiche::QuicheTextUtils::HexEncode(associated_data)
-                      << " actual: "
-                      << quiche::QuicheTextUtils::HexEncode(
-                             decrypter_->associated_data_);
+                      << absl::BytesToHexString(associated_data) << " actual: "
+                      << absl::BytesToHexString(decrypter_->associated_data_);
       return false;
     }
     absl::string_view ciphertext(
@@ -782,12 +781,10 @@
             retry_token_length_length, retry_token_length, length_length)));
     if (ciphertext != decrypter_->ciphertext_) {
       QUIC_LOG(ERROR) << "Decrypted incorrect ciphertext data.  expected "
-                      << quiche::QuicheTextUtils::HexEncode(ciphertext)
-                      << " actual: "
-                      << quiche::QuicheTextUtils::HexEncode(
-                             decrypter_->ciphertext_)
+                      << absl::BytesToHexString(ciphertext) << " actual: "
+                      << absl::BytesToHexString(decrypter_->ciphertext_)
                       << " associated data: "
-                      << quiche::QuicheTextUtils::HexEncode(associated_data);
+                      << absl::BytesToHexString(associated_data);
       return false;
     }
     return true;
diff --git a/quic/core/quic_packets.cc b/quic/core/quic_packets.cc
index 0325909..3d6228e 100644
--- a/quic/core/quic_packets.cc
+++ b/quic/core/quic_packets.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
 #include "net/third_party/quiche/src/quic/core/quic_types.h"
@@ -263,7 +264,7 @@
   }
   if (header.nonce != nullptr) {
     os << ", diversification_nonce: "
-       << quiche::QuicheTextUtils::HexEncode(
+       << absl::BytesToHexString(
               absl::string_view(header.nonce->data(), header.nonce->size()));
   }
   os << ", packet_number: " << header.packet_number << " }\n";
diff --git a/quic/core/quic_tag.cc b/quic/core/quic_tag.cc
index 2858924..ed7ae17 100644
--- a/quic/core/quic_tag.cc
+++ b/quic/core/quic_tag.cc
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "absl/base/macros.h"
+#include "absl/strings/escaping.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
@@ -60,8 +61,8 @@
     return std::string(chars, sizeof(chars));
   }
 
-  return quiche::QuicheTextUtils::HexEncode(
-      reinterpret_cast<const char*>(&orig_tag), sizeof(orig_tag));
+  return absl::BytesToHexString(absl::string_view(
+      reinterpret_cast<const char*>(&orig_tag), sizeof(orig_tag)));
 }
 
 uint32_t MakeQuicTag(char a, char b, char c, char d) {
@@ -78,7 +79,7 @@
   quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tag_string);
   std::string tag_bytes;
   if (tag_string.length() == 8) {
-    tag_bytes = quiche::QuicheTextUtils::HexDecode(tag_string);
+    tag_bytes = absl::HexStringToBytes(tag_string);
     tag_string = tag_bytes;
   }
   QuicTag tag = 0;
diff --git a/quic/test_tools/crypto_test_utils.cc b/quic/test_tools/crypto_test_utils.cc
index e8535d8..00f7f1b 100644
--- a/quic/test_tools/crypto_test_utils.cc
+++ b/quic/test_tools/crypto_test_utils.cc
@@ -9,6 +9,7 @@
 #include <string>
 #include <utility>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "third_party/boringssl/src/include/openssl/bn.h"
 #include "third_party/boringssl/src/include/openssl/ec.h"
@@ -705,7 +706,7 @@
     if (value_len > 0 && value[0] == '#') {
       // This is ascii encoded hex.
       std::string hex_value =
-          quiche::QuicheTextUtils::HexDecode(absl::string_view(&value[1]));
+          absl::HexStringToBytes(absl::string_view(&value[1]));
       msg.SetStringPiece(quic_tag, hex_value);
       continue;
     }
@@ -831,14 +832,14 @@
   std::string nonce;
   CryptoUtils::GenerateNonce(clock->WallNow(), QuicRandom::GetInstance(), orbit,
                              &nonce);
-  return ("#" + quiche::QuicheTextUtils::HexEncode(nonce));
+  return ("#" + absl::BytesToHexString(nonce));
 }
 
 std::string GenerateClientPublicValuesHex() {
   char public_value[32];
   memset(public_value, 42, sizeof(public_value));
-  return ("#" + quiche::QuicheTextUtils::HexEncode(public_value,
-                                                   sizeof(public_value)));
+  return ("#" + absl::BytesToHexString(
+                    absl::string_view(public_value, sizeof(public_value))));
 }
 
 void GenerateFullCHLO(
diff --git a/quic/test_tools/crypto_test_utils_test.cc b/quic/test_tools/crypto_test_utils_test.cc
index 45bcec4..0769da4 100644
--- a/quic/test_tools/crypto_test_utils_test.cc
+++ b/quic/test_tools/crypto_test_utils_test.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/proto/crypto_server_config_proto.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
@@ -139,12 +140,12 @@
   std::string nonce;
   CryptoUtils::GenerateNonce(clock.WallNow(), QuicRandom::GetInstance(), orbit,
                              &nonce);
-  std::string nonce_hex = "#" + quiche::QuicheTextUtils::HexEncode(nonce);
+  std::string nonce_hex = "#" + absl::BytesToHexString(nonce);
 
   char public_value[32];
   memset(public_value, 42, sizeof(public_value));
-  std::string pub_hex = "#" + quiche::QuicheTextUtils::HexEncode(
-                                  public_value, sizeof(public_value));
+  std::string pub_hex = "#" + absl::BytesToHexString(absl::string_view(
+                                  public_value, sizeof(public_value)));
 
   // The methods below use a PROTOCOL_QUIC_CRYPTO version so we pick the
   // first one from the list of supported versions.
diff --git a/quic/tools/quic_packet_printer_bin.cc b/quic/tools/quic_packet_printer_bin.cc
index 6f9a658..cfe0b8d 100644
--- a/quic/tools/quic_packet_printer_bin.cc
+++ b/quic/tools/quic_packet_printer_bin.cc
@@ -33,6 +33,7 @@
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
 #include "absl/strings/string_view.h"
+#include "absl/strings/escaping.h"
 
 DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
                               quic_version,
@@ -99,16 +100,16 @@
   bool OnStreamFrame(const QuicStreamFrame& frame) override {
     std::cerr << "OnStreamFrame: " << frame;
     std::cerr << "         data: { "
-              << quiche::QuicheTextUtils::HexEncode(frame.data_buffer,
-                                                    frame.data_length)
+              << absl::BytesToHexString(
+                     absl::string_view(frame.data_buffer, frame.data_length))
               << " }\n";
     return true;
   }
   bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
     std::cerr << "OnCryptoFrame: " << frame;
     std::cerr << "         data: { "
-              << quiche::QuicheTextUtils::HexEncode(frame.data_buffer,
-                                                    frame.data_length)
+              << absl::BytesToHexString(
+                     absl::string_view(frame.data_buffer, frame.data_length))
               << " }\n";
     return true;
   }
@@ -263,7 +264,7 @@
     quic::QuicPrintCommandLineFlagHelp(usage);
     return 1;
   }
-  std::string hex = quiche::QuicheTextUtils::HexDecode(args[1]);
+  std::string hex = absl::HexStringToBytes(args[1]);
   quic::ParsedQuicVersionVector versions = quic::AllSupportedVersions();
   // Fake a time since we're not actually generating acks.
   quic::QuicTime start(quic::QuicTime::Zero());
diff --git a/quic/tools/quic_toy_client.cc b/quic/tools/quic_toy_client.cc
index c4b36db..0b34e88 100644
--- a/quic/tools/quic_toy_client.cc
+++ b/quic/tools/quic_toy_client.cc
@@ -48,6 +48,7 @@
 #include <utility>
 #include <vector>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/quic/core/quic_packets.h"
 #include "net/third_party/quiche/src/quic/core/quic_server_id.h"
@@ -321,7 +322,7 @@
   if (!GetQuicFlag(FLAGS_body_hex).empty()) {
     DCHECK(GetQuicFlag(FLAGS_body).empty())
         << "Only set one of --body and --body_hex.";
-    body = QuicheTextUtils::HexDecode(GetQuicFlag(FLAGS_body_hex));
+    body = absl::HexStringToBytes(GetQuicFlag(FLAGS_body_hex));
   }
 
   // Construct a GET or POST request for supplied URL.
@@ -358,8 +359,8 @@
       if (!GetQuicFlag(FLAGS_body_hex).empty()) {
         // Print the user provided hex, rather than binary body.
         std::cout << "body:\n"
-                  << QuicheTextUtils::HexDump(QuicheTextUtils::HexDecode(
-                         GetQuicFlag(FLAGS_body_hex)))
+                  << QuicheTextUtils::HexDump(
+                         absl::HexStringToBytes(GetQuicFlag(FLAGS_body_hex)))
                   << std::endl;
       } else {
         std::cout << "body: " << body << std::endl;