Skip to content

fix: Caesar cipher produces non-alphabetic output for negative shifts#7508

Merged
DenizAltunkapan merged 2 commits into
TheAlgorithms:masterfrom
herley-shaori:fix/caesar-negative-shift
Jul 3, 2026
Merged

fix: Caesar cipher produces non-alphabetic output for negative shifts#7508
DenizAltunkapan merged 2 commits into
TheAlgorithms:masterfrom
herley-shaori:fix/caesar-negative-shift

Conversation

@herley-shaori

Copy link
Copy Markdown
Contributor

Fixes #7506

Problem

Caesar.encode/Caesar.decode produced corrupted, non-alphabetic output for any negative shift that is not an exact multiple of 26:

new Caesar().encode("A", -1); // returned "@" (ASCII 64) instead of "Z"

Root cause: normalizeShift did (char) (shift % 26). Java's % preserves the dividend's sign, so -1 % 26 == -1, and casting a negative int to the unsigned 16-bit char type wraps it to 65535. The following char arithmetic then overflowed and truncated into an arbitrary wrong character, which the > 'Z' / < 'A' wraparound checks could not catch. This also broke the decode(encode(x, s), s) == x round-trip for negative shifts.

Fix

  • normalizeShift now returns an int normalized into 0..25 via ((shift % 26) + 26) % 26, so a negative shift is mapped to its equivalent positive rotation (e.g. -125).
  • The shift arithmetic in encode/decode is performed in int and cast back to char only when appending, which also removes the lossy-conversions compound-assignment pattern.

Tests

Added three regression tests to CaesarTest:

  • caesarEncryptWithNegativeShiftTestencode("A", -1) must wrap to "Z" (upper and lower case).
  • caesarDecryptWithNegativeShiftTest — decoding with a negative shift.
  • caesarNegativeShiftRoundTripTest — encode→decode round-trip for shifts -1, -5, -25, -26, -27, -52.

Verified locally: mvn test -Dtest=CaesarTest → 6/6 pass, mvn checkstyle:check clean, clang-format --dry-run --Werror clean. All existing tests still pass unchanged.

normalizeShift cast a possibly-negative int directly to char, which
wraps to a huge unsigned 16-bit value (e.g. (char) -1 == 65535). The
subsequent char arithmetic then overflowed and emitted characters
outside the Latin alphabet, e.g. encode("A", -1) returned '@' instead
of 'Z', and the encode/decode round-trip was broken for negative
shifts.

Normalize the shift into the 0..25 range with ((shift % 26) + 26) % 26
and perform the character arithmetic in int, casting back to char only
when appending. Add regression tests covering negative shifts and the
encode/decode round-trip.

Fixes TheAlgorithms#7506
@codecov-commenter

codecov-commenter commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.25%. Comparing base (c6fa50f) to head (5625af5).

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #7508      +/-   ##
============================================
+ Coverage     80.23%   80.25%   +0.01%     
- Complexity     7355     7358       +3     
============================================
  Files           810      810              
  Lines         23785    23787       +2     
  Branches       4678     4678              
============================================
+ Hits          19085    19091       +6     
  Misses         3940     3940              
+ Partials        760      756       -4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@DenizAltunkapan DenizAltunkapan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@herley-shaori thanks!

@DenizAltunkapan DenizAltunkapan enabled auto-merge (squash) July 3, 2026 21:11
@DenizAltunkapan DenizAltunkapan merged commit 12ea4bb into TheAlgorithms:master Jul 3, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Caesar cipher produces non-alphabetic garbage output for negative shifts

3 participants