Daily Challenge #32 - Hide Phone Numbers

thepracticaldev profile image dev.to staff ・1 min read

For this challenge, write a function that encrypts phone numbers. The method should hide the last six digits of each phone number.

Example 1 (Using US phone number)
IN: 201-680-0202 => OUT: 201-6XX-XXXX

You can also have the code check the validity of the phone number's format.

Example 2
IN: 145-201-680-0202 => OUT: false

Feel free to apply this challenge to phone numbers outside the USA as well.

Good luck!

This challenge comes from user otrebor6. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge for a future post? Email yo+challenge@dev.to with your suggestions!

Posted on by:

thepracticaldev profile

dev.to staff


The hardworking team behind dev.to ❀️


Editor guide


.hide-phone-number {
  display: inline-block;
  font-family: monospace, monospace;
  position: relative;

.hide-phone-number::after {
  content: "XX-XXXX";
  background: white;
  position: absolute;
  right: 0;

Another trickery with CSS: with no prechecks and assuming the phone number is valid, add the class "hide-phone-number" to the element and the last six digit will turn into Xs.


Ah, this is like people making the text background black on PDF documents and being surprised when people can still just copy & paste the original contents out of the "redacted" document.


It's exactly that :P


CSS assassin spotted


Outstanding move



function obfuscatePhone(number) {
  if (!/^\d{3}-\d{3}-\d{4}$/.test(number)) return false;
  return number.replace(/\d(?=(?:-?\d){0,5}$)/g, 'X');

But it could be any language that supports look-aheads in regular expressions πŸ˜‰


This is not "encryption".


I usually don't get caught up on semantics, but I'm with you on this one. Idk why not-encrypted encryption irks me πŸ€·β€β™€οΈ

Me: okay, cool. Code review almost passed, but can you encrypt that one var?
Jr, 2 days later: here you go, I md5'd it.
Me: πŸ₯ΊπŸ€―πŸ’€βš°οΈπŸ’”


Well depends on the definition of "Encryption". If encryption means that you are hide information from not allowed authorities and you say no one is allowed to see these numbers, than this is encryption.


Err, no. You don't get to pick your own definition for words.

Encryption is "the process of converting information or data into a code, especially to prevent unauthorized access". The main point being, it can be decrypted. You can't decrypt data that has been deleted.

If you want to remove information it's called e.g. "redacting" or "obscuring".

"Encryption is the process of converting data to an unrecognizable or "encrypted" form. It is commonly used to protect sensitive information so that only authorized parties can view it." (techterms.com/definition/encryption)

"In cryptography, encryption is the process of encoding a message or information in such a way that only authorized parties can access it and those who are not authorized cannot." (en.wikipedia.org/wiki/Encryption)

I would guess there are multiple definitions and not the one and only! I would not say that encryption is wrong in this context, but "data anonymization" would be the better wording here.

"so that only authorized parties can view it" - you can't view it if you can't decrypt it

"encoding a message or information in such a way that only authorized parties can access it" - authorized parties can't decode XXX-XXXX

These are all the exact same thing.


Today I'm folding the other way around. I've chosen not to validate the number format because I didn't want to spend the entire evening building a regex that matched all possible formats I can think of.

import Data.Char (isDigit)

hide_nums :: String -> String
hide_nums = snd . foldr kevin (0, "")
        kevin :: Char -> (Int, String) -> (Int, String)
        kevin char (x, result)
            | x >= 6       = (x, char:result)
            | isDigit char = (x + 1, 'x':result)
            | otherwise    = (x, char:result)

There no package for phone numbers?


Using a library kinda defeats the purpose of these exercises, don't you think?

But what's the fun in that?

Yes I'm just asking πŸ˜„ of there are one I'll use it, working with phone number is a bit hardwork since others country had different types phone code.



defmodule Phone do
  def hide(string = <<plain::binary-size(5), hidden::binary>>) do
    String.match?(string, ~r/\d{3}-\d{3}-\d{4}/) &&
      plain <> String.replace(hidden, ~r/\d/, "X")

Uses some bitstring pattern matching :)



const hideNumbers = num => num.match(/^\d{3}\-\d{3}\-\d{4}$/) 
                           ? num.substring(0,5) + num.substring(5).replace(/\d/g, "X")
                           : false;

Live demo on CodePen.


My python sol :

import re

def hide_number(phone):
    if re.match(r"^(?:\d{3}-){2}\d{4}", phone):
        return re.sub(r"\d{2}-\d{4}", "XX-XXXX", phone, 2)
        return False

One liner (lambda exp) :

hide_number = lambda phone: re.sub(r"\d{2}-\d{4}", "XX-XXXX", phone, 2) \  
       if re.match(r"^(?:\d{3}-){2}\d{4}", phone) else False


def hide(n):
    n = n.replace('-', '')
    if len(n) < 10 or len(n) > 10 or n.isdigit() == False :  return False
    return '%s-%s-%s' %(n[:3],n[3:6],n[6:])
// Indian Phone Number
"9560661273".slice(0,4) + "*".repeat(6)