diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc
index cd98b29b1ea..376885cdd8e 100644
--- a/src/core/lib/channel/channelz.cc
+++ b/src/core/lib/channel/channelz.cc
@@ -36,6 +36,7 @@
 #include "src/core/lib/gprpp/memory.h"
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/slice/b64.h"
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/server.h"
@@ -303,11 +304,16 @@ static void PopulateSocketAddressJson(grpc_json* json, const char* name,
     } else {
       char* host = nullptr;
       char* port = nullptr;
-      GPR_ASSERT(gpr_split_host_port(host_port, &host, &port));
-      if (port != nullptr) {
-        port_num = atoi(port);
+      if (strcmp(uri->scheme, "localhost") == 0) {
+        host = gpr_strdup("::1");
+        port_num = atoi(uri->path);
+      } else {
+        GPR_ASSERT(gpr_split_host_port(host_port, &host, &port));
+        if (port != nullptr) {
+          port_num = atoi(port);
+        }
       }
-      char* b64_host = gpr_string_base64_encode(host);
+      char* b64_host = grpc_base64_encode(host, strlen(host), false, false);
       json_iterator =
           grpc_json_create_child(json_iterator, json, "tcpip_address", nullptr,
                                  GRPC_JSON_OBJECT, false);
diff --git a/src/core/lib/gpr/string.cc b/src/core/lib/gpr/string.cc
index 5672b7a2b93..0a76fc1f54a 100644
--- a/src/core/lib/gpr/string.cc
+++ b/src/core/lib/gpr/string.cc
@@ -156,51 +156,6 @@ int gpr_parse_bytes_to_uint32(const char* buf, size_t len, uint32_t* result) {
   return 1;
 }
 
-static const char alphabet[] =
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-static const uint8_t tail_xtra[3] = {0, 2, 3};
-
-char* gpr_string_base64_encode(const char* in) {
-  size_t in_len = strlen(in);
-  size_t in_triplets = in_len / 3;
-  size_t tail_case = in_len % 3;
-  size_t out_length = in_triplets * 4 + tail_xtra[tail_case];
-  char* output = static_cast<char*>(gpr_malloc(out_length + 1));
-  char* out = output;
-  size_t i;
-
-  /* encode full triplets */
-  for (i = 0; i < in_triplets; i++) {
-    out[0] = alphabet[in[0] >> 2];
-    out[1] = alphabet[((in[0] & 0x3) << 4) | (in[1] >> 4)];
-    out[2] = alphabet[((in[1] & 0xf) << 2) | (in[2] >> 6)];
-    out[3] = alphabet[in[2] & 0x3f];
-    out += 4;
-    in += 3;
-  }
-
-  /* encode the remaining bytes */
-  switch (tail_case) {
-    case 0:
-      break;
-    case 1:
-      out[0] = alphabet[in[0] >> 2];
-      out[1] = alphabet[(in[0] & 0x3) << 4];
-      out += 2;
-      in += 1;
-      break;
-    case 2:
-      out[0] = alphabet[in[0] >> 2];
-      out[1] = alphabet[((in[0] & 0x3) << 4) | (in[1] >> 4)];
-      out[2] = alphabet[(in[1] & 0xf) << 2];
-      out += 3;
-      in += 2;
-      break;
-  }
-  out[0] = '\0';
-  return output;
-}
-
 void gpr_reverse_bytes(char* str, int len) {
   char *p1, *p2;
   for (p1 = str, p2 = str + len - 1; p2 > p1; ++p1, --p2) {
diff --git a/src/core/lib/gpr/string.h b/src/core/lib/gpr/string.h
index 1bb50196e82..ce51fe46321 100644
--- a/src/core/lib/gpr/string.h
+++ b/src/core/lib/gpr/string.h
@@ -41,9 +41,6 @@ char* gpr_dump(const char* buf, size_t len, uint32_t flags);
 int gpr_parse_bytes_to_uint32(const char* data, size_t length,
                               uint32_t* result);
 
-/* returns allocated string with the base64 encoding of in */
-char* gpr_string_base64_encode(const char* in);
-
 /* Minimum buffer size for calling ltoa */
 #define GPR_LTOA_MIN_BUFSIZE (3 * sizeof(long))