diff --git a/src/console.c b/src/console.c
index 2b3ee0e227c06863d07ce083c74b24b744820614..44bb03a3de1507484379dd97d07fae2d7cb6f06e 100644
--- a/src/console.c
+++ b/src/console.c
@@ -544,6 +544,22 @@ static void CON_MoveConsole(void)
 	}
 }
 
+INT32 CON_ShiftChar(INT32 ch)
+{
+	if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
+	{
+		if (shiftdown ^ capslock)
+			ch = shiftxform[ch];
+	}
+	else	// if we're holding shift we should still shift non letter symbols
+	{
+		if (shiftdown)
+			ch = shiftxform[ch];
+	}
+
+	return ch;
+}
+
 // Clear time of console heads up messages
 //
 void CON_ClearHUD(void)
diff --git a/src/console.h b/src/console.h
index 98df6ee2b032a8c75512e31792f3603db0be4005..11621746cdbae9cfaf437c9bf64ef63cbed870de 100644
--- a/src/console.h
+++ b/src/console.h
@@ -44,6 +44,8 @@ extern UINT8 *yellowmap, *purplemap, *greenmap, *bluemap, *graymap, *redmap, *or
 // Console bg color (auto updated to match)
 extern UINT8 *consolebgmap;
 
+INT32 CON_ShiftChar(INT32 ch);
+
 void CON_SetupBackColormap(void);
 void CON_ClearHUD(void); // clear heads up messages
 
diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index 0202ff6f44a7f34289f2efa046f232d304a1f5c8..5fe378e021ae977ce4d68d52dc160cc9b3793574 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -2228,24 +2228,8 @@ boolean CL_Responder(event_t *ev)
 		len = strlen(cl_challengepassword);
 		if (len < 64)
 		{
-
-			// shifting code stolen from lat by fickle, thx :)
-
-			// I know this looks very messy but this works. If it ain't broke, don't fix it!
-			// shift LETTERS to uppercase if we have capslock or are holding shift
-			if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
-			{
-				if (shiftdown ^ capslock)
-					ch = shiftxform[ch];
-			}
-			else	// if we're holding shift we should still shift non letter symbols
-			{
-				if (shiftdown)
-					ch = shiftxform[ch];
-			}
-
 			cl_challengepassword[len+1] = 0;
-			cl_challengepassword[len] = ch;
+			cl_challengepassword[len] = CON_ShiftChar(ch);
 		}
 
 		cl_challengeattempted = 0;
diff --git a/src/hu_stuff.c b/src/hu_stuff.c
index a540e0a11db3ba1d51ba9fc4dedc44363d889bbd..b43570735968dbb7dcca67f4ce14558cc90fbc28 100644
--- a/src/hu_stuff.c
+++ b/src/hu_stuff.c
@@ -1293,18 +1293,7 @@ boolean HU_Responder(event_t *ev)
 		&& ev->data1 != gamecontrol[gc_talkkey][1]))
 			return false;
 
-		// I know this looks very messy but this works. If it ain't broke, don't fix it!
-		// shift LETTERS to uppercase if we have capslock or are holding shift
-		if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
-		{
-			if (shiftdown ^ capslock)
-				c = shiftxform[c];
-		}
-		else	// if we're holding shift we should still shift non letter symbols
-		{
-			if (shiftdown)
-				c = shiftxform[c];
-		}
+		c = CON_ShiftChar(c);
 
 		// pasting. pasting is cool. chat is a bit limited, though :(
 		if (((c == 'v' || c == 'V') && ctrldown) && !CHAT_MUTE)