diff --git a/base/files/file_path.cc b/base/files/file_path.cc
index 92123533aaa55..51656d26d3af5 100644
--- a/base/files/file_path.cc
+++ b/base/files/file_path.cc
@@ -10,9 +10,6 @@
 #include "base/basictypes.h"
 #include "base/logging.h"
 #include "base/pickle.h"
-
-// These includes are just for the *Hack functions, and should be removed
-// when those functions are removed.
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
@@ -1259,11 +1256,12 @@ int FilePath::CompareIgnoreCase(StringPieceType string1,
 
 #else  // << WIN. MACOSX | other (POSIX) >>
 
-// Generic (POSIX) implementation of file string comparison.
-// TODO(rolandsteiner) check if this is sufficient/correct.
+// Generic Posix system comparisons.
 int FilePath::CompareIgnoreCase(StringPieceType string1,
                                 StringPieceType string2) {
-  int comparison = strcasecmp(string1.data(), string2.data());
+  // Specifically need null termianted strings for this API call.
+  int comparison = strcasecmp(string1.as_string().c_str(),
+                              string2.as_string().c_str());
   if (comparison < 0)
     return -1;
   if (comparison > 0)
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc
index 5b727ce0b4e2a..fcd8ddf12e4ed 100644
--- a/base/strings/string_util.cc
+++ b/base/strings/string_util.cc
@@ -140,6 +140,53 @@ bool IsWprintfFormatPortable(const wchar_t* format) {
   return true;
 }
 
+template<class StringType>
+int CompareCaseInsensitiveASCIIT(BasicStringPiece<StringType> a,
+                                 BasicStringPiece<StringType> b) {
+  // Find the first characters that aren't equal and compare them.  If the end
+  // of one of the strings is found before a nonequal character, the lengths
+  // of the strings are compared.
+  size_t i = 0;
+  while (i < a.length() && i < b.length()) {
+    typename StringType::value_type lower_a = ToLowerASCII(a[i]);
+    typename StringType::value_type lower_b = ToLowerASCII(b[i]);
+    if (lower_a < lower_b)
+      return -1;
+    if (lower_a > lower_b)
+      return 1;
+    i++;
+  }
+
+  // End of one string hit before finding a different character. Expect the
+  // common case to be "strings equal" at this point so check that first.
+  if (a.length() == b.length())
+    return 0;
+
+  if (a.length() < b.length())
+    return -1;
+  return 1;
+}
+
+int CompareCaseInsensitiveASCII(base::StringPiece a, base::StringPiece b) {
+  return CompareCaseInsensitiveASCIIT<std::string>(a, b);
+}
+
+int CompareCaseInsensitiveASCII(base::StringPiece16 a, base::StringPiece16 b) {
+  return CompareCaseInsensitiveASCIIT<base::string16>(a, b);
+}
+
+bool EqualsCaseInsensitiveASCII(base::StringPiece a, base::StringPiece b) {
+  if (a.length() != b.length())
+    return false;
+  return CompareCaseInsensitiveASCIIT<std::string>(a, b) == 0;
+}
+
+bool EqualsCaseInsensitiveASCII(base::StringPiece16 a, base::StringPiece16 b) {
+  if (a.length() != b.length())
+    return false;
+  return CompareCaseInsensitiveASCIIT<base::string16>(a, b) == 0;
+}
+
 const std::string& EmptyString() {
   return EmptyStrings::GetInstance()->s;
 }
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index 62b3605a8933b..5d26f1c54142f 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -21,20 +21,10 @@
 
 namespace base {
 
-// C standard-library functions like "strncasecmp" and "snprintf" that aren't
-// cross-platform are provided as "base::strncasecmp", and their prototypes
-// are listed below.  These functions are then implemented as inline calls
-// to the platform-specific equivalents in the platform-specific headers.
-
-// Compares the two strings s1 and s2 without regard to case using
-// the current locale; returns 0 if they are equal, 1 if s1 > s2, and -1 if
-// s2 > s1 according to a lexicographic comparison.
-int strcasecmp(const char* s1, const char* s2);
-
-// Compares up to count characters of s1 and s2 without regard to case using
-// the current locale; returns 0 if they are equal, 1 if s1 > s2, and -1 if
-// s2 > s1 according to a lexicographic comparison.
-int strncasecmp(const char* s1, const char* s2, size_t count);
+// C standard-library functions that aren't cross-platform are provided as
+// "base::...", and their prototypes are listed below. These functions are
+// then implemented as inline calls to the platform-specific equivalents in the
+// platform-specific headers.
 
 // Wrapper for vsnprintf that always null-terminates and always returns the
 // number of characters that would be in an untruncated formatted
@@ -56,6 +46,19 @@ inline int snprintf(char* buffer, size_t size, const char* format, ...) {
   return result;
 }
 
+// TODO(mark) http://crbug.com/472900 crashpad shouldn't use base while
+// being DEPSed in. This backwards-compat hack is provided until crashpad is
+// updated.
+#if defined(OS_WIN)
+inline int strcasecmp(const char* s1, const char* s2) {
+  return _stricmp(s1, s2);
+}
+#else  // Posix
+inline int strcasecmp(const char* string1, const char* string2) {
+  return ::strcasecmp(string1, string2);
+}
+#endif
+
 // BSD-style safe and consistent string copy functions.
 // Copies |src| to |dst|, where |dst_size| is the total allocated size of |dst|.
 // Copies at most |dst_size|-1 characters, and always NULL terminates |dst|, as
@@ -102,10 +105,13 @@ template <class Char> inline Char ToUpperASCII(Char c) {
 
 // Function objects to aid in comparing/searching strings.
 
+// DO NOT USE. tolower() will given incorrect results for non-ASCII characters.
+// Use the ASCII version, base::i18n::ToLower, or base::i18n::FoldCase.
 template<typename Char> struct CaseInsensitiveCompare {
  public:
   bool operator()(Char x, Char y) const {
     // TODO(darin): Do we really want to do locale sensitive comparisons here?
+    // ANSWER(brettw): No.
     // See http://crbug.com/24917
     return tolower(x) == tolower(y);
   }
@@ -118,6 +124,22 @@ template<typename Char> struct CaseInsensitiveCompareASCII {
   }
 };
 
+// Like strcasecmp for case-insensitive ASCII characters only. Returns:
+//   -1  (a < b)
+//    0  (a == b)
+//    1  (a > b)
+// (unlike strcasecmp which can return values greater or less than 1/-1). For
+// full Unicode support, use base::i18n::ToLower or base::i18h::FoldCase
+// and then just call the normal string operators on the result.
+BASE_EXPORT int CompareCaseInsensitiveASCII(StringPiece a, StringPiece b);
+BASE_EXPORT int CompareCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b);
+
+// Equality for ASCII case-insensitive comparisons. For full Unicode support,
+// use base::i18n::ToLower or base::i18h::FoldCase and then compare with either
+// == or !=.
+BASE_EXPORT bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b);
+BASE_EXPORT bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b);
+
 // These threadsafe functions return references to globally unique empty
 // strings.
 //
diff --git a/base/strings/string_util_posix.h b/base/strings/string_util_posix.h
index d31a9fcbefd28..9e96697ff5625 100644
--- a/base/strings/string_util_posix.h
+++ b/base/strings/string_util_posix.h
@@ -20,14 +20,6 @@ inline char* strdup(const char* str) {
   return ::strdup(str);
 }
 
-inline int strcasecmp(const char* string1, const char* string2) {
-  return ::strcasecmp(string1, string2);
-}
-
-inline int strncasecmp(const char* string1, const char* string2, size_t count) {
-  return ::strncasecmp(string1, string2, count);
-}
-
 inline int vsnprintf(char* buffer, size_t size,
                      const char* format, va_list arguments) {
   return ::vsnprintf(buffer, size, format, arguments);
diff --git a/base/strings/string_util_unittest.cc b/base/strings/string_util_unittest.cc
index 02b184cc62023..1593f8189679a 100644
--- a/base/strings/string_util_unittest.cc
+++ b/base/strings/string_util_unittest.cc
@@ -1056,6 +1056,26 @@ TEST(StringUtilTest, ContainsOnlyChars) {
                                   kWhitespaceUTF16));
 }
 
+TEST(StringUtilTest, CompareCaseInsensitiveASCII) {
+  EXPECT_EQ(0, CompareCaseInsensitiveASCII("", ""));
+  EXPECT_EQ(0, CompareCaseInsensitiveASCII("Asdf", "aSDf"));
+
+  // Differing lengths.
+  EXPECT_EQ(-1, CompareCaseInsensitiveASCII("Asdf", "aSDfA"));
+  EXPECT_EQ(1, CompareCaseInsensitiveASCII("AsdfA", "aSDf"));
+
+  // Differing values.
+  EXPECT_EQ(-1, CompareCaseInsensitiveASCII("AsdfA", "aSDfb"));
+  EXPECT_EQ(1, CompareCaseInsensitiveASCII("Asdfb", "aSDfA"));
+}
+
+TEST(StringUtilTest, EqualsCaseInsensitiveASCII) {
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII("", ""));
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII("Asdf", "aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII("bsdf", "aSDF"));
+  EXPECT_FALSE(EqualsCaseInsensitiveASCII("Asdf", "aSDFz"));
+}
+
 class WriteIntoTest : public testing::Test {
  protected:
   static void WritesCorrectly(size_t num_chars) {
diff --git a/base/strings/string_util_win.h b/base/strings/string_util_win.h
index 7c1e34cf8fcff..839a799a157f0 100644
--- a/base/strings/string_util_win.h
+++ b/base/strings/string_util_win.h
@@ -20,14 +20,6 @@ inline char* strdup(const char* str) {
   return _strdup(str);
 }
 
-inline int strcasecmp(const char* s1, const char* s2) {
-  return _stricmp(s1, s2);
-}
-
-inline int strncasecmp(const char* s1, const char* s2, size_t count) {
-  return _strnicmp(s1, s2, count);
-}
-
 inline int vsnprintf(char* buffer, size_t size,
                      const char* format, va_list arguments) {
   int length = vsnprintf_s(buffer, size, size - 1, format, arguments);
diff --git a/chrome/browser/media_galleries/fileapi/media_path_filter.cc b/chrome/browser/media_galleries/fileapi/media_path_filter.cc
index 0212e11136035..5b27f1019ab28 100644
--- a/chrome/browser/media_galleries/fileapi/media_path_filter.cc
+++ b/chrome/browser/media_galleries/fileapi/media_path_filter.cc
@@ -126,15 +126,12 @@ bool MediaPathFilter::ShouldSkip(const base::FilePath& path) {
   const char win_98_recycle_bin_name[] = "RECYCLED";
   const char win_xp_recycle_bin_name[] = "RECYCLER";
   const char win_vista_recycle_bin_name[] = "$Recycle.bin";
-  if ((base::strncasecmp(base_name.c_str(),
-                         win_98_recycle_bin_name,
-                         strlen(win_98_recycle_bin_name)) == 0) ||
-      (base::strncasecmp(base_name.c_str(),
-                         win_xp_recycle_bin_name,
-                         strlen(win_xp_recycle_bin_name)) == 0) ||
-      (base::strncasecmp(base_name.c_str(),
-                         win_vista_recycle_bin_name,
-                         strlen(win_vista_recycle_bin_name)) == 0))
+  if (base::StartsWith(base_name, win_98_recycle_bin_name,
+                       base::CompareCase::INSENSITIVE_ASCII) ||
+      base::StartsWith(base_name, win_xp_recycle_bin_name,
+                       base::CompareCase::INSENSITIVE_ASCII) ||
+      base::StartsWith(base_name, win_vista_recycle_bin_name,
+                       base::CompareCase::INSENSITIVE_ASCII))
     return true;
 #endif  // defined(OS_WIN)
   return false;
diff --git a/chrome/browser/net/sdch_browsertest.cc b/chrome/browser/net/sdch_browsertest.cc
index 7a1cb7b69211d..9c93d6b841dda 100644
--- a/chrome/browser/net/sdch_browsertest.cc
+++ b/chrome/browser/net/sdch_browsertest.cc
@@ -108,7 +108,7 @@ bool GetRequestHeader(const HttpRequestHeaderMap& map,
                       std::string* value) {
   for (HttpRequestHeaderMap::const_iterator it = map.begin();
        it != map.end(); ++it) {
-    if (!base::strcasecmp(it->first.c_str(), header)) {
+    if (base::EqualsCaseInsensitiveASCII(it->first, header)) {
       *value = it->second;
       return true;
     }
@@ -170,7 +170,7 @@ class SdchResponseHandler {
       return false;
     base::StringTokenizer tokenizer(value, " ,");
     while (tokenizer.GetNext()) {
-      if (base::strcasecmp(tokenizer.token().c_str(), "sdch"))
+      if (base::EqualsCaseInsensitiveASCII(tokenizer.token(), "sdch"))
         return true;
     }
     return false;
diff --git a/chrome/browser/printing/printing_layout_browsertest.cc b/chrome/browser/printing/printing_layout_browsertest.cc
index 4e1d2b731d83b..4755a18a00755 100644
--- a/chrome/browser/printing/printing_layout_browsertest.cc
+++ b/chrome/browser/printing/printing_layout_browsertest.cc
@@ -207,7 +207,7 @@ class PrintingLayoutTest : public PrintingTest<InProcessBrowserTest>,
       base::FilePath file;
       while (!(file = enumerator.Next()).empty()) {
         std::wstring ext = file.Extension();
-        if (base::strcasecmp(base::WideToUTF8(ext).c_str(), ".emf") == 0) {
+        if (base::EqualsCaseInsensitiveASCII(base::WideToUTF8(ext), ".emf")) {
           EXPECT_FALSE(found_emf) << "Found a leftover .EMF file: \"" <<
               emf_file << "\" and \"" << file.value() <<
               "\" when looking for \"" << verification_name << "\"";
@@ -215,7 +215,7 @@ class PrintingLayoutTest : public PrintingTest<InProcessBrowserTest>,
           emf_file = file.value();
           continue;
         }
-        if (base::strcasecmp(base::WideToUTF8(ext).c_str(), ".prn") == 0) {
+        if (base::EqualsCaseInsensitiveASCII(base::WideToUTF8(ext), ".prn")) {
           EXPECT_FALSE(found_prn) << "Found a leftover .PRN file: \"" <<
               prn_file << "\" and \"" << file.value() <<
               "\" when looking for \"" << verification_name << "\"";
diff --git a/chrome/service/cloud_print/cloud_print_connector.cc b/chrome/service/cloud_print/cloud_print_connector.cc
index a1f6be7f667ae..f53c865e6abe7 100644
--- a/chrome/service/cloud_print/cloud_print_connector.cc
+++ b/chrome/service/cloud_print/cloud_print_connector.cc
@@ -653,7 +653,7 @@ void CloudPrintConnector::OnReceivePrinterCaps(
 
 bool CloudPrintConnector::IsSamePrinter(const std::string& name1,
                                         const std::string& name2) const {
-  return (0 == base::strcasecmp(name1.c_str(), name2.c_str()));
+  return base::EqualsCaseInsensitiveASCII(name1, name2);
 }
 
 }  // namespace cloud_print
diff --git a/chrome/service/cloud_print/cloud_print_proxy_backend.cc b/chrome/service/cloud_print/cloud_print_proxy_backend.cc
index f93215dbd66fb..53485ccdf1618 100644
--- a/chrome/service/cloud_print/cloud_print_proxy_backend.cc
+++ b/chrome/service/cloud_print/cloud_print_proxy_backend.cc
@@ -550,8 +550,8 @@ void CloudPrintProxyBackend::Core::OnIncomingNotification(
 
   DCHECK(base::MessageLoop::current() == backend_->core_thread_.message_loop());
   VLOG(1) << "CP_CONNECTOR: Incoming notification.";
-  if (0 == base::strcasecmp(kCloudPrintPushNotificationsSource,
-                            notification.channel.c_str()))
+  if (base::EqualsCaseInsensitiveASCII(kCloudPrintPushNotificationsSource,
+                                       notification.channel))
     HandlePrinterNotification(notification.data);
 }
 
diff --git a/chrome/test/chromedriver/performance_logger.cc b/chrome/test/chromedriver/performance_logger.cc
index 37e66f40f2803..f97385b6d9143 100644
--- a/chrome/test/chromedriver/performance_logger.cc
+++ b/chrome/test/chromedriver/performance_logger.cc
@@ -43,7 +43,8 @@ bool IsEnabled(const PerfLoggingPrefs::InspectorDomainStatus& domain_status) {
 bool ShouldRequestTraceEvents(const std::string& command) {
   for (size_t i_domain = 0; i_domain < arraysize(kRequestTraceCommands);
        ++i_domain) {
-    if (base::strcasecmp(command.c_str(), kRequestTraceCommands[i_domain]) == 0)
+    if (base::EqualsCaseInsensitiveASCII(command,
+                                         kRequestTraceCommands[i_domain]))
       return true;
   }
   return false;
diff --git a/components/mime_util/mime_util.cc b/components/mime_util/mime_util.cc
index 3841fbbb69074..ef5e0daaefdda 100644
--- a/components/mime_util/mime_util.cc
+++ b/components/mime_util/mime_util.cc
@@ -221,8 +221,8 @@ net::CertificateMimeType GetCertificateMimeTypeForMimeType(
   // Don't create a map, there is only one entry in the table,
   // except on Android.
   for (size_t i = 0; i < arraysize(kSupportedCertificateTypes); ++i) {
-    if (base::strcasecmp(mime_type.c_str(),
-                         kSupportedCertificateTypes[i].mime_type) == 0) {
+    if (base::EqualsCaseInsensitiveASCII(
+            mime_type, kSupportedCertificateTypes[i].mime_type)) {
       return kSupportedCertificateTypes[i].cert_type;
     }
   }
diff --git a/components/policy/core/common/registry_dict_win.cc b/components/policy/core/common/registry_dict_win.cc
index 132adcaddea05..dd04beec1ab68 100644
--- a/components/policy/core/common/registry_dict_win.cc
+++ b/components/policy/core/common/registry_dict_win.cc
@@ -136,7 +136,7 @@ scoped_ptr<base::Value> ConvertValue(const base::Value& value,
 
 bool CaseInsensitiveStringCompare::operator()(const std::string& a,
                                               const std::string& b) const {
-  return base::strcasecmp(a.c_str(), b.c_str()) < 0;
+  return base::CompareCaseInsensitiveASCII(a, b) < 0;
 }
 
 RegistryDict::RegistryDict() {}
diff --git a/content/common/service_worker/service_worker_types.h b/content/common/service_worker/service_worker_types.h
index 917c9ed9ff405..631c56320deb2 100644
--- a/content/common/service_worker/service_worker_types.h
+++ b/content/common/service_worker/service_worker_types.h
@@ -102,7 +102,7 @@ enum ServiceWorkerFetchEventResult {
 
 struct ServiceWorkerCaseInsensitiveCompare {
   bool operator()(const std::string& lhs, const std::string& rhs) const {
-    return base::strcasecmp(lhs.c_str(), rhs.c_str()) < 0;
+    return base::CompareCaseInsensitiveASCII(lhs, rhs) < 0;
   }
 };
 
diff --git a/content/plugin/webplugin_proxy.cc b/content/plugin/webplugin_proxy.cc
index 3c607143ee892..6b6d696ca5da8 100644
--- a/content/plugin/webplugin_proxy.cc
+++ b/content/plugin/webplugin_proxy.cc
@@ -280,7 +280,7 @@ void WebPluginProxy::HandleURLRequest(const char* url,
                                       int notify_id,
                                       bool popups_allowed,
                                       bool notify_redirects) {
- if (!target && (0 == base::strcasecmp(method, "GET"))) {
+ if (!target && base::EqualsCaseInsensitiveASCII(method, "GET")) {
     // Please refer to https://bugzilla.mozilla.org/show_bug.cgi?id=366082
     // for more details on this.
     if (delegate_->GetQuirks() &
diff --git a/device/usb/usb_service_impl.cc b/device/usb/usb_service_impl.cc
index ea7ad7f498108..2261ad6930bdd 100644
--- a/device/usb/usb_service_impl.cc
+++ b/device/usb/usb_service_impl.cc
@@ -127,10 +127,9 @@ bool IsWinUsbInterface(const std::string& device_path) {
   }
 
   USB_LOG(DEBUG) << "Driver for " << device_path << " is " << buffer << ".";
-  if (base::strncasecmp("WinUSB", (const char*)&buffer[0], sizeof "WinUSB") ==
-      0) {
+  if (base::StartsWith(reinterpret_cast<const char*>(buffer), "WinUSB",
+                       base::CompareCase::INSENSITIVE_ASCII))
     return true;
-  }
   return false;
 }
 
diff --git a/extensions/browser/api/web_request/form_data_parser.cc b/extensions/browser/api/web_request/form_data_parser.cc
index 31b6fe8aadfa1..f12c34face959 100644
--- a/extensions/browser/api/web_request/form_data_parser.cc
+++ b/extensions/browser/api/web_request/form_data_parser.cc
@@ -315,11 +315,11 @@ scoped_ptr<FormDataParser> FormDataParser::CreateFromContentTypeHeader(
     const std::string content_type(
         content_type_header->substr(0, content_type_header->find(';')));
 
-    if (base::strcasecmp(
-        content_type.c_str(), "application/x-www-form-urlencoded") == 0) {
+    if (base::EqualsCaseInsensitiveASCII(content_type,
+                                         "application/x-www-form-urlencoded")) {
       choice = URL_ENCODED;
-    } else if (base::strcasecmp(
-        content_type.c_str(), "multipart/form-data") == 0) {
+    } else if (base::EqualsCaseInsensitiveASCII(content_type,
+                                                "multipart/form-data")) {
       static const char kBoundaryString[] = "boundary=";
       size_t offset = content_type_header->find(kBoundaryString);
       if (offset == std::string::npos) {
diff --git a/media/video/capture/fake_video_capture_device_factory.cc b/media/video/capture/fake_video_capture_device_factory.cc
index a9d32dee2eda1..302223fd7ed43 100644
--- a/media/video/capture/fake_video_capture_device_factory.cc
+++ b/media/video/capture/fake_video_capture_device_factory.cc
@@ -26,7 +26,7 @@ scoped_ptr<VideoCaptureDevice> FakeVideoCaptureDeviceFactory::Create(
   FakeVideoCaptureDevice::FakeVideoCaptureDeviceType fake_vcd_type;
   if (option.empty())
     fake_vcd_type = FakeVideoCaptureDevice::USING_OWN_BUFFERS;
-  else if (base:: strcasecmp(option.c_str(), "triplanar") == 0)
+  else if (base::EqualsCaseInsensitiveASCII(option, "triplanar"))
     fake_vcd_type = FakeVideoCaptureDevice::USING_OWN_BUFFERS_TRIPLANAR;
   else
     fake_vcd_type = FakeVideoCaptureDevice::USING_CLIENT_BUFFERS;
diff --git a/mojo/services/network/http_connection_impl.cc b/mojo/services/network/http_connection_impl.cc
index 2df12aa7b50d7..ad3347d9d43ca 100644
--- a/mojo/services/network/http_connection_impl.cc
+++ b/mojo/services/network/http_connection_impl.cc
@@ -375,11 +375,12 @@ void HttpConnectionImpl::OnFinishedReadingResponseBody(
       //
       // TODO(yzshen): Consider adding to net::HttpServerResponseInfo a simple
       // setter for body which doesn't fiddle with headers.
-      if (base::strcasecmp(header.name.data(),
-                           net::HttpRequestHeaders::kContentLength) == 0) {
+      base::StringPiece name_piece(header.name.data(), header.name.size());
+      if (base::EqualsCaseInsensitiveASCII(
+              name_piece, net::HttpRequestHeaders::kContentLength)) {
         continue;
-      } else if (base::strcasecmp(header.name.data(),
-                                  net::HttpRequestHeaders::kContentType) == 0) {
+      } else if (base::EqualsCaseInsensitiveASCII(
+                     name_piece, net::HttpRequestHeaders::kContentType)) {
         content_type = header.value;
         continue;
       }
diff --git a/net/base/mime_sniffer.cc b/net/base/mime_sniffer.cc
index 907c7c4f09989..668e89831f808 100644
--- a/net/base/mime_sniffer.cc
+++ b/net/base/mime_sniffer.cc
@@ -344,8 +344,10 @@ static bool MatchMagicNumber(const char* content,
   bool match = false;
   if (magic_entry.is_string) {
     if (content_strlen >= len) {
-      // String comparisons are case-insensitive
-      match = (base::strncasecmp(magic_entry.magic, content, len) == 0);
+      // Do a case-insensitive prefix comparison.
+      DCHECK_EQ(strlen(magic_entry.magic), len);
+      match = base::EqualsCaseInsensitiveASCII(magic_entry.magic,
+                                               base::StringPiece(content, len));
     }
   } else {
     if (size >= len) {
@@ -462,11 +464,12 @@ static bool SniffForOfficeDocs(const char* content,
     if (url_path.length() < kOfficeExtensionTypes[i].extension_len)
       continue;
 
-    const char* extension =
-        &url_path[url_path.length() - kOfficeExtensionTypes[i].extension_len];
-
-    if (0 == base::strncasecmp(extension, kOfficeExtensionTypes[i].extension,
-                               kOfficeExtensionTypes[i].extension_len)) {
+    base::StringPiece extension = base::StringPiece(url_path).substr(
+        url_path.length() - kOfficeExtensionTypes[i].extension_len);
+    if (base::EqualsCaseInsensitiveASCII(
+            extension,
+            base::StringPiece(kOfficeExtensionTypes[i].extension,
+                              kOfficeExtensionTypes[i].extension_len))) {
       type = kOfficeExtensionTypes[i].doc_type;
       break;
     }
@@ -608,14 +611,22 @@ static bool SniffXML(const char* content,
     if (!pos)
       return false;
 
-    if ((pos + sizeof("<?xml") - 1 <= end) &&
-        (base::strncasecmp(pos, "<?xml", sizeof("<?xml") - 1) == 0)) {
+    static const char kXmlPrefix[] = "<?xml";
+    static const size_t kXmlPrefixLength = arraysize(kXmlPrefix) - 1;
+    static const char kDocTypePrefix[] = "<!DOCTYPE";
+    static const size_t kDocTypePrefixLength = arraysize(kDocTypePrefix) - 1;
+
+    if ((pos + kXmlPrefixLength <= end) &&
+        base::EqualsCaseInsensitiveASCII(
+            base::StringPiece(pos, kXmlPrefixLength),
+            base::StringPiece(kXmlPrefix, kXmlPrefixLength))) {
       // Skip XML declarations.
       ++pos;
       continue;
-    } else if ((pos + sizeof("<!DOCTYPE") - 1 <= end) &&
-               (base::strncasecmp(pos, "<!DOCTYPE", sizeof("<!DOCTYPE") - 1) ==
-                0)) {
+    } else if ((pos + kDocTypePrefixLength <= end) &&
+               base::EqualsCaseInsensitiveASCII(
+                   base::StringPiece(pos, kDocTypePrefixLength),
+                   base::StringPiece(kDocTypePrefix, kDocTypePrefixLength))) {
       // Skip DOCTYPE declarations.
       ++pos;
       continue;
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc
index ae4781a68ae82..27c547b6e0b37 100644
--- a/net/base/mime_util.cc
+++ b/net/base/mime_util.cc
@@ -116,8 +116,11 @@ const char* FindMimeType(const MimeInfo* mappings,
     const char* extensions = mappings[i].extensions;
     for (;;) {
       size_t end_pos = strcspn(extensions, ",");
+      // The length check is required to prevent the StringPiece below from
+      // including uninitialized memory if ext is longer than extensions.
       if (end_pos == ext.size() &&
-          base::strncasecmp(extensions, ext.data(), ext.size()) == 0)
+          base::EqualsCaseInsensitiveASCII(
+              base::StringPiece(extensions, ext.size()), ext))
         return mappings[i].mime_type;
       extensions += end_pos;
       if (!*extensions)
@@ -268,13 +271,10 @@ bool MimeUtil::MatchesMimeType(const std::string& mime_type_pattern,
 
   const std::string::size_type star = base_pattern.find('*');
   if (star == std::string::npos) {
-    if (base_pattern.size() == base_type.size() &&
-        base::strncasecmp(base_pattern.data(), base_type.data(),
-                          base_pattern.size()) == 0) {
+    if (base::EqualsCaseInsensitiveASCII(base_pattern, base_type))
       return MatchesMimeTypeParameters(mime_type_pattern, mime_type);
-    } else {
+    else
       return false;
-    }
   }
 
   // Test length to prevent overlap between |left| and |right|.
diff --git a/net/cookies/cookie_util.cc b/net/cookies/cookie_util.cc
index 2723363e2fb4e..b9c7e8d601f8e 100644
--- a/net/cookies/cookie_util.cc
+++ b/net/cookies/cookie_util.cc
@@ -125,7 +125,8 @@ base::Time ParseCookieTime(const std::string& time_string) {
       if (!found_month) {
         for (int i = 0; i < kMonthsLen; ++i) {
           // Match prefix, so we could match January, etc
-          if (base::strncasecmp(token.c_str(), kMonths[i], 3) == 0) {
+          if (base::StartsWith(token, base::StringPiece(kMonths[i], 3),
+                               base::CompareCase::INSENSITIVE_ASCII)) {
             exploded.month = i + 1;
             found_month = true;
             break;
diff --git a/net/dns/dns_response.cc b/net/dns/dns_response.cc
index 64db818b2b942..730206ca60801 100644
--- a/net/dns/dns_response.cc
+++ b/net/dns/dns_response.cc
@@ -303,7 +303,7 @@ DnsResponse::Result DnsResponse::ParseToAddressList(
       if (!ip_addresses.empty())
         return DNS_CNAME_AFTER_ADDRESS;
 
-      if (base::strcasecmp(record.name.c_str(), expected_name.c_str()) != 0)
+      if (!base::EqualsCaseInsensitiveASCII(record.name, expected_name))
         return DNS_NAME_MISMATCH;
 
       if (record.rdata.size() !=
@@ -315,7 +315,7 @@ DnsResponse::Result DnsResponse::ParseToAddressList(
       if (record.rdata.size() != expected_size)
         return DNS_SIZE_MISMATCH;
 
-      if (base::strcasecmp(record.name.c_str(), expected_name.c_str()) != 0)
+      if (!base::EqualsCaseInsensitiveASCII(record.name, expected_name))
         return DNS_NAME_MISMATCH;
 
       ttl_sec = std::min(ttl_sec, record.ttl);
diff --git a/net/http/http_log_util.cc b/net/http/http_log_util.cc
index 0467fb605ab40..8e071e34109a7 100644
--- a/net/http/http_log_util.cc
+++ b/net/http/http_log_util.cc
@@ -45,15 +45,15 @@ std::string ElideHeaderValueForNetLog(NetLogCaptureMode capture_mode,
     // Note: this logic should be kept in sync with stripCookiesAndLoginInfo in
     // chrome/browser/resources/net_internals/log_view_painter.js.
 
-    if (!base::strcasecmp(header.c_str(), "set-cookie") ||
-        !base::strcasecmp(header.c_str(), "set-cookie2") ||
-        !base::strcasecmp(header.c_str(), "cookie") ||
-        !base::strcasecmp(header.c_str(), "authorization") ||
-        !base::strcasecmp(header.c_str(), "proxy-authorization")) {
+    if (base::EqualsCaseInsensitiveASCII(header, "set-cookie") ||
+        base::EqualsCaseInsensitiveASCII(header, "set-cookie2") ||
+        base::EqualsCaseInsensitiveASCII(header, "cookie") ||
+        base::EqualsCaseInsensitiveASCII(header, "authorization") ||
+        base::EqualsCaseInsensitiveASCII(header, "proxy-authorization")) {
       redact_begin = value.begin();
       redact_end = value.end();
-    } else if (!base::strcasecmp(header.c_str(), "www-authenticate") ||
-               !base::strcasecmp(header.c_str(), "proxy-authenticate")) {
+    } else if (base::EqualsCaseInsensitiveASCII(header, "www-authenticate") ||
+               base::EqualsCaseInsensitiveASCII(header, "proxy-authenticate")) {
       // Look for authentication information from data received from the server
       // in multi-round Negotiate authentication.
       HttpAuthChallengeTokenizer challenge(value.begin(), value.end());
diff --git a/net/http/http_request_headers.cc b/net/http/http_request_headers.cc
index 004d0659512c6..c2eee59af95f8 100644
--- a/net/http/http_request_headers.cc
+++ b/net/http/http_request_headers.cc
@@ -241,8 +241,7 @@ HttpRequestHeaders::HeaderVector::iterator
 HttpRequestHeaders::FindHeader(const base::StringPiece& key) {
   for (HeaderVector::iterator it = headers_.begin();
        it != headers_.end(); ++it) {
-    if (key.length() == it->key.length() &&
-        !base::strncasecmp(key.data(), it->key.data(), key.length()))
+    if (base::EqualsCaseInsensitiveASCII(key, it->key))
       return it;
   }
 
@@ -253,8 +252,7 @@ HttpRequestHeaders::HeaderVector::const_iterator
 HttpRequestHeaders::FindHeader(const base::StringPiece& key) const {
   for (HeaderVector::const_iterator it = headers_.begin();
        it != headers_.end(); ++it) {
-    if (key.length() == it->key.length() &&
-        !base::strncasecmp(key.data(), it->key.data(), key.length()))
+    if (base::EqualsCaseInsensitiveASCII(key, it->key))
       return it;
   }
 
diff --git a/net/tools/balsa/balsa_headers.h b/net/tools/balsa/balsa_headers.h
index 3edcf677703b7..3fc01c4c157a0 100644
--- a/net/tools/balsa/balsa_headers.h
+++ b/net/tools/balsa/balsa_headers.h
@@ -538,7 +538,7 @@ class BalsaHeaders {
       do {
         iterator_base::increment();
       } while (!AtEnd() &&
-               !StringPieceUtils::EqualIgnoreCase(key_, (**this).first));
+               !base::EqualsCaseInsensitiveASCII(key_, (**this).first));
       return *this;
     }
 
diff --git a/net/tools/balsa/string_piece_utils.h b/net/tools/balsa/string_piece_utils.h
index 7d8a1aaaee287..6d8967a014219 100644
--- a/net/tools/balsa/string_piece_utils.h
+++ b/net/tools/balsa/string_piece_utils.h
@@ -65,31 +65,10 @@ struct StringPieceCaseHash {
 };
 #endif  // COMPILER_MSVC
 
-struct StringPieceUtils {
-  // ASCII case-insensitive equality.
-  static bool EqualIgnoreCase(const base::StringPiece& piece1,
-                              const base::StringPiece& piece2) {
-    base::StringPiece::const_iterator p1i = piece1.begin();
-    base::StringPiece::const_iterator p2i = piece2.begin();
-    if (piece1.empty() && piece2.empty()) {
-      return true;
-    } else if (piece1.size() != piece2.size()) {
-      return false;
-    }
-    while (p1i != piece1.end() && p2i != piece2.end()) {
-      if (base::ToLowerASCII(*p1i) != base::ToLowerASCII(*p2i))
-        return false;
-      ++p1i;
-      ++p2i;
-    }
-    return true;
-  }
-};
-
 struct StringPieceCaseEqual {
   bool operator()(const base::StringPiece& piece1,
                   const base::StringPiece& piece2) const {
-    return StringPieceUtils::EqualIgnoreCase(piece1, piece2);
+    return base::EqualsCaseInsensitiveASCII(piece1, piece2);
   }
 };
 
diff --git a/net/tools/quic/test_tools/http_message.cc b/net/tools/quic/test_tools/http_message.cc
index ad13f5c2f45d3..b1520917b43cb 100644
--- a/net/tools/quic/test_tools/http_message.cc
+++ b/net/tools/quic/test_tools/http_message.cc
@@ -158,8 +158,8 @@ void HTTPMessage::ValidateMessage() const {
   for (vector<StringPiece>::iterator it = transfer_encodings.begin();
        it != transfer_encodings.end();
        ++it) {
-    CHECK(StringPieceUtils::EqualIgnoreCase("identity", *it) ||
-          StringPieceUtils::EqualIgnoreCase("chunked", *it)) << *it;
+    CHECK(base::EqualsCaseInsensitiveASCII("identity", *it) ||
+          base::EqualsCaseInsensitiveASCII("chunked", *it)) << *it;
   }
 
   vector<StringPiece> content_lengths;
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc
index fde6568d73916..80e421628a48d 100644
--- a/net/url_request/url_request_http_job_unittest.cc
+++ b/net/url_request/url_request_http_job_unittest.cc
@@ -77,7 +77,7 @@ class URLRequestHttpJobTest : public ::testing::Test {
     for (const std::string& token :
          base::SplitString(encoding_headers, ", ", base::KEEP_WHITESPACE,
                            base::SPLIT_WANT_NONEMPTY)) {
-      if (!base::strncasecmp(token.data(), "sdch", token.length()))
+      if (base::EqualsCaseInsensitiveASCII(token, "sdch"))
         return true;
     }
     return false;
diff --git a/printing/backend/cups_helper.cc b/printing/backend/cups_helper.cc
index c0271b2a2872f..79e33fcf705b8 100644
--- a/printing/backend/cups_helper.cc
+++ b/printing/backend/cups_helper.cc
@@ -49,48 +49,45 @@ void ParseLpOptions(const base::FilePath& filepath,
   const char kDefault[] = "default";
   const size_t kDestLen = sizeof(kDest) - 1;
   const size_t kDefaultLen = sizeof(kDefault) - 1;
-  std::vector<std::string> lines;
-  base::SplitString(content, '\n', &lines);
 
-  for (size_t i = 0; i < lines.size(); ++i) {
-    std::string line = lines[i];
-    if (line.empty())
-      continue;
-
-    if (base::strncasecmp (line.c_str(), kDefault, kDefaultLen) == 0 &&
+  for (base::StringPiece line :
+       base::SplitStringPiece(content, "\n", base::KEEP_WHITESPACE,
+                              base::SPLIT_WANT_NONEMPTY)) {
+    if (base::StartsWith(line, base::StringPiece(kDefault, kDefaultLen),
+                         base::CompareCase::INSENSITIVE_ASCII) &&
         isspace(line[kDefaultLen])) {
       line = line.substr(kDefaultLen);
-    } else if (base::strncasecmp (line.c_str(), kDest, kDestLen) == 0 &&
+    } else if (base::StartsWith(line, base::StringPiece(kDest, kDestLen),
+                                base::CompareCase::INSENSITIVE_ASCII) &&
                isspace(line[kDestLen])) {
       line = line.substr(kDestLen);
     } else {
       continue;
     }
 
-    base::TrimWhitespaceASCII(line, base::TRIM_ALL, &line);
+    line = base::TrimWhitespaceASCII(line, base::TRIM_ALL);
     if (line.empty())
       continue;
 
     size_t space_found = line.find(' ');
-    if (space_found == std::string::npos)
+    if (space_found == base::StringPiece::npos)
       continue;
 
-    std::string name = line.substr(0, space_found);
+    base::StringPiece name = line.substr(0, space_found);
     if (name.empty())
       continue;
 
-    if (base::strncasecmp(printer_name.c_str(), name.c_str(),
-                          name.length()) != 0) {
+    if (!base::EqualsCaseInsensitiveASCII(printer_name, name))
       continue;  // This is not the required printer.
-    }
 
     line = line.substr(space_found + 1);
     // Remove extra spaces.
-    base::TrimWhitespaceASCII(line, base::TRIM_ALL, &line);
+    line = base::TrimWhitespaceASCII(line, base::TRIM_ALL);
     if (line.empty())
       continue;
-    // Parse the selected printer custom options.
-    *num_options = cupsParseOptions(line.c_str(), 0, options);
+    // Parse the selected printer custom options. Need to pass a
+    // null-terminated string.
+    *num_options = cupsParseOptions(line.as_string().c_str(), 0, options);
   }
 }
 
@@ -157,9 +154,12 @@ bool GetBasicColorModelSettings(ppd_file_t* ppd,
 
   if (marked_choice) {
     *color_is_default =
-        (base::strcasecmp(marked_choice->choice, printing::kBlack) != 0) &&
-        (base::strcasecmp(marked_choice->choice, printing::kGray) != 0) &&
-        (base::strcasecmp(marked_choice->choice, printing::kGrayscale) != 0);
+        !base::EqualsCaseInsensitiveASCII(marked_choice->choice,
+                                          printing::kBlack) &&
+        !base::EqualsCaseInsensitiveASCII(marked_choice->choice,
+                                          printing::kGray) &&
+        !base::EqualsCaseInsensitiveASCII(marked_choice->choice,
+                                          printing::kGrayscale);
   }
   return true;
 }
@@ -190,10 +190,12 @@ bool GetPrintOutModeColorSettings(ppd_file_t* ppd,
                                            printout_mode->defchoice);
   }
   if (printout_mode_choice) {
-    if ((base::strcasecmp(printout_mode_choice->choice,
-                          printing::kNormalGray) == 0) ||
-        (base::strcasecmp(printout_mode_choice->choice, kHighGray) == 0) ||
-        (base::strcasecmp(printout_mode_choice->choice, kDraftGray) == 0)) {
+    if (base::EqualsCaseInsensitiveASCII(printout_mode_choice->choice,
+                                         printing::kNormalGray) ||
+        base::EqualsCaseInsensitiveASCII(printout_mode_choice->choice,
+                                         kHighGray) ||
+        base::EqualsCaseInsensitiveASCII(printout_mode_choice->choice,
+                                          kDraftGray)) {
       *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY;
       *color_is_default = false;
     }
@@ -223,8 +225,8 @@ bool GetColorModeSettings(ppd_file_t* ppd,
   }
 
   if (mode_choice) {
-    *color_is_default =
-        (base::strcasecmp(mode_choice->choice, printing::kColor) == 0);
+    *color_is_default = base::EqualsCaseInsensitiveASCII(
+        mode_choice->choice, printing::kColor);
   }
   return true;
 }
@@ -249,8 +251,8 @@ bool GetHPColorSettings(ppd_file_t* ppd,
                                 color_mode_option->defchoice);
   }
   if (mode_choice) {
-    *color_is_default =
-        (base::strcasecmp(mode_choice->choice, printing::kColor) == 0);
+    *color_is_default = base::EqualsCaseInsensitiveASCII(
+        mode_choice->choice, printing::kColor);
   }
   return true;
 }
@@ -279,8 +281,8 @@ bool GetProcessColorModelSettings(ppd_file_t* ppd,
   }
 
   if (mode_choice) {
-    *color_is_default =
-        (base::strcasecmp(mode_choice->choice, printing::kGreyscale) != 0);
+    *color_is_default = !base::EqualsCaseInsensitiveASCII(
+        mode_choice->choice, printing::kGreyscale);
   }
   return true;
 }
@@ -383,7 +385,7 @@ bool ParsePpdCapabilities(
 
   if (duplex_choice) {
     caps.duplex_capable = true;
-    if (base::strcasecmp(duplex_choice->choice, kDuplexNone) != 0)
+    if (!base::EqualsCaseInsensitiveASCII(duplex_choice->choice, kDuplexNone))
       caps.duplex_default = printing::LONG_EDGE;
     else
       caps.duplex_default = printing::SIMPLEX;
diff --git a/skia/ext/image_operations_bench.cc b/skia/ext/image_operations_bench.cc
index 4fd81bc0b331f..b5464c64d37f7 100644
--- a/skia/ext/image_operations_bench.cc
+++ b/skia/ext/image_operations_bench.cc
@@ -50,7 +50,7 @@ const StringMethodPair resize_methods[] = {
 bool StringToMethod(const std::string& arg,
                     skia::ImageOperations::ResizeMethod* method) {
   for (size_t i = 0; i < arraysize(resize_methods); ++i) {
-    if (base::strcasecmp(arg.c_str(), resize_methods[i].name) == 0) {
+    if (base::EqualsCaseInsensitiveASCII(arg, resize_methods[i].name)) {
       *method = resize_methods[i].method;
       return true;
     }
diff --git a/sql/connection.cc b/sql/connection.cc
index d1b104908c988..d07d425eb1721 100644
--- a/sql/connection.cc
+++ b/sql/connection.cc
@@ -992,7 +992,8 @@ bool Connection::DoesColumnExist(const char* table_name,
     return false;
 
   while (statement.Step()) {
-    if (!base::strcasecmp(statement.ColumnString(1).c_str(), column_name))
+    if (base::EqualsCaseInsensitiveASCII(statement.ColumnString(1),
+                                         column_name))
       return true;
   }
   return false;
diff --git a/tools/gn/filesystem_utils.cc b/tools/gn/filesystem_utils.cc
index c98db86484c1a..42736c9fbfa69 100644
--- a/tools/gn/filesystem_utils.cc
+++ b/tools/gn/filesystem_utils.cc
@@ -83,7 +83,7 @@ bool AreAbsoluteWindowsPathsEqual(const base::StringPiece& a,
     return false;
 
   // For now, just do a case-insensitive ASCII comparison. We could convert to
-  // UTF-16 and use ICU if necessary. Or maybe base::strcasecmp is good enough?
+  // UTF-16 and use ICU if necessary.
   for (size_t i = 0; i < a.size(); i++) {
     if (NormalizeWindowsPathChar(a[i]) != NormalizeWindowsPathChar(b[i]))
       return false;
diff --git a/ui/base/l10n/l10n_util.cc b/ui/base/l10n/l10n_util.cc
index 4182f42ec6d46..0ef20ba41b235 100644
--- a/ui/base/l10n/l10n_util.cc
+++ b/ui/base/l10n/l10n_util.cc
@@ -205,7 +205,7 @@ bool IsDuplicateName(const std::string& locale_name) {
     return !base::EndsWith(locale_name, "419", true);
 
   for (size_t i = 0; i < arraysize(kDuplicateNames); ++i) {
-    if (base::strcasecmp(kDuplicateNames[i], locale_name.c_str()) == 0)
+    if (base::EqualsCaseInsensitiveASCII(kDuplicateNames[i], locale_name))
       return true;
   }
   return false;
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc
index 543c62596bc19..775fb1c38c577 100644
--- a/ui/gfx/render_text_harfbuzz.cc
+++ b/ui/gfx/render_text_harfbuzz.cc
@@ -530,7 +530,7 @@ class HarfBuzzLineBreaker {
 // Function object for case insensitive string comparison.
 struct CaseInsensitiveCompare {
   bool operator() (const std::string& a, const std::string& b) const {
-    return base::strncasecmp(a.c_str(), b.c_str(), b.length()) < 0;
+    return base::CompareCaseInsensitiveASCII(a, b) < 0;
   }
 };
 
diff --git a/ui/gfx/test/fontconfig_util_linux.cc b/ui/gfx/test/fontconfig_util_linux.cc
index e2f5140b682cf..609a3fca8bdae 100644
--- a/ui/gfx/test/fontconfig_util_linux.cc
+++ b/ui/gfx/test/fontconfig_util_linux.cc
@@ -100,8 +100,7 @@ bool LoadFontIntoFontconfig(const base::FilePath& path) {
 bool LoadSystemFontIntoFontconfig(const std::string& basename) {
   for (size_t i = 0; i < kNumSystemFontsForFontconfig; ++i) {
     base::FilePath path(kSystemFontsForFontconfig[i]);
-    if (base::strcasecmp(path.BaseName().value().c_str(), basename.c_str()) ==
-        0)
+    if (base::EqualsCaseInsensitiveASCII(path.BaseName().value(), basename))
       return LoadFontIntoFontconfig(path);
   }
   LOG(ERROR) << "Unable to find system font named " << basename;