UPDATE: I know this doesn't fully answer the question but noting the ability to change the code to an id or remove the subject code is now an extension: https://lab.civicrm.org/extensions/caseidinsubject
I originally had some doubts, but in 7 years have never had a problem, but for one org we removed the hash and just use the actual case id by editing the civimail template, and see code below for the processing side. It also accepts just [1234] without the # symbol. This was more for staff ease of use than for the recipient - this way they can send from their email program and bcc the email processor.
I don't have a scientific study to reference, but anecdotally many non-technical people don't "read" emails the same way people who stare at code all day do. Your experience may be different.
Here's the block from CRM/Activity/BAO/Activity.php that has the modification:
$matches = array();
$subj_to_match = CRM_Utils_Array::value('subject', $params);
if (preg_match('/\[case #([0-9a-h]{7})\]/', $subj_to_match, $matches)) {
$key = CRM_Core_DAO::escapeString(CIVICRM_SITE_KEY);
$hash = $matches[1];
$query = "SELECT id FROM civicrm_case WHERE SUBSTR(SHA1(CONCAT('$key', id)), 1, 7) = '$hash'";
} elseif (preg_match('/\[case #(\d+)\]/', $subj_to_match, $matches)) {
$hash = $matches[1];
// this seems like an odd query but we are checking the id actually exists
$query = "SELECT id FROM civicrm_case WHERE id = '$hash'";
} elseif (preg_match('/\[#(\d+)\]/', $subj_to_match, $matches)) {
// technically this is a subset of the one below, but keeping it allows a subject that had both and prioritize this one
$hash = $matches[1];
// this seems like an odd query but we are checking the id actually exists
$query = "SELECT id FROM civicrm_case WHERE id = '$hash'";
} elseif (preg_match('/\[(\d+)\]/', $subj_to_match, $matches)) {
$hash = $matches[1];
// this seems like an odd query but we are checking the id actually exists
$query = "SELECT id FROM civicrm_case WHERE id = '$hash'";
}
if (!empty($matches)) {
$caseParams = array(
'activity_id' => $activity->id,
'case_id' => CRM_Core_DAO::singleValueQuery($query),
);
if ($caseParams['case_id']) {
$merge_info = CRM_Mergetrack_BAO_Mergetrack::getLatest(array('type' => 'civicrm_case', 'id' => $caseParams['case_id']));
if (!empty($merge_info)) {
$caseParams['case_id'] = $merge_info['new_id'];
}
CRM_Case_BAO_Case::processCaseActivity($caseParams);
}
else {
self::logActivityAction($activity, "unknown case hash encountered: $hash");
}
}
The "mergetrack" part is a separate extension (I'd call it unstable and it has some core hacks). Recently the same org has started sending out emails automatically on case creation, and then often the case has been merged in between the time the email goes out and the reply comes back, and so it was getting filed on the deleted case. You can remove those 4 lines.