Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
CC = gcc
CFLAGS = -Wall -Wextra -pedantic -std=c11
TARGET = sifreleyici
SRC = sifreleyicim/sifreleyicim1/sifreleyici.c

all: $(TARGET)

$(TARGET): $(SRC)
$(CC) $(CFLAGS) -o $(TARGET) $(SRC)

clean:
rm -f $(TARGET)

.PHONY: all clean
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,29 @@
# Ceasar_Cipher_Decoder_and_Encoder
Program that encrypts and decrypts texts according to the Caesar Cipher algorithm

Linux terminalinde çalışan Caesar Cipher (şifreleme/çözme) uygulaması.

## Özellikler

- Tamamen terminal tabanlı akış (Linux uyumlu)
- Metni direkt konsoldan alır (zorunlu dosya bağımlılığı yok)
- Encode için pozitif/negatif/büyük kaydırma desteği
- Decode için 26 olası varyantı listeler
- Büyük-küçük harf korunur, harf dışı karakterler aynen bırakılır

## Derleme

```bash
make
```

Alternatif olarak doğrudan GCC:

```bash
gcc -Wall -Wextra -pedantic -std=c11 -o sifreleyici sifreleyicim/sifreleyicim1/sifreleyici.c
```

## Çalıştırma

```bash
./sifreleyici
```
212 changes: 85 additions & 127 deletions sifreleyicim/sifreleyicim1/sifreleyici.c
Original file line number Diff line number Diff line change
@@ -1,171 +1,129 @@
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_UZUNLUK 2000
#define ALFABE_UZUNLUGU 26

int can_file_open(FILE* input_file, FILE* output_file) {
if (input_file == NULL || output_file == NULL) {
perror("FILE ERROR");

return 1; // hata kodu döndür
int normalize_shift(int kaydirma) {
int normalized = kaydirma % ALFABE_UZUNLUGU;
if (normalized < 0) {
normalized += ALFABE_UZUNLUGU;
}
return 0; // başarı
return normalized;
}

void Kucuk_Harf_Dizi(char dizi[], FILE* input_file) {
int i = 0, ch;
while ((ch = fgetc(input_file)) != EOF && i < MAX_UZUNLUK - 1) {
dizi[i] = tolower((unsigned char)ch);
i++;
void satir_oku(char dizi[], size_t boyut) {
if (fgets(dizi, (int)boyut, stdin) == NULL) {
dizi[0] = '\0';
return;
}

dizi[i] = '\0';
size_t len = strlen(dizi);
if (len > 0 && dizi[len - 1] == '\n') {
dizi[len - 1] = '\0';
}
}
Comment on lines +17 to 27

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect the EOF/truncation path from satir_oku() into sayi_oku() and main().
sed -n '17,27p' sifreleyicim/sifreleyicim1/sifreleyici.c
printf '\n-- sayi_oku --\n'
sed -n '62,76p' sifreleyicim/sifreleyicim1/sifreleyici.c
printf '\n-- main loop --\n'
sed -n '91,98p' sifreleyicim/sifreleyicim1/sifreleyici.c

Repository: ukis666/Ceasar_Cipher_Decoder_and_Encoder

Length of output: 879


🏁 Script executed:

sed -n '85,110p' sifreleyicim/sifreleyicim1/sifreleyici.c

Repository: ukis666/Ceasar_Cipher_Decoder_and_Encoder

Length of output: 570


Differentiate EOF/truncation from ordinary invalid input.

When fgets() returns NULL (EOF from Ctrl-D or closed stdin), the code converts it to an empty string, treating it as invalid input rather than a signal to exit. This traps the loop in an infinite "Gecersiz secim" cycle with no way to break. If input exceeds the buffer size, the missing newline goes undetected, and unread characters remain in stdin, causing the next prompt to consume stale input.

To fix: return a read status from satir_oku() (0 for EOF, 1 for success), drain unread input when no newline is found, have sayi_oku() return -1 on EOF, and let main() check for EOF and break before treating empty input as an invalid choice.

Suggested direction
-void satir_oku(char dizi[], size_t boyut) {
+int satir_oku(char dizi[], size_t boyut) {
     if (fgets(dizi, (int)boyut, stdin) == NULL) {
         dizi[0] = '\0';
-        return;
+        return 0;
     }
 
     size_t len = strlen(dizi);
     if (len > 0 && dizi[len - 1] == '\n') {
         dizi[len - 1] = '\0';
+    } else {
+        int ch;
+        while ((ch = getchar()) != '\n' && ch != EOF) {
+        }
     }
+
+    return 1;
 }
-        if (!sayi_oku("", &secim)) {
+        int ok = sayi_oku("", &secim);
+        if (ok < 0) {
+            break;
+        }
+        if (!ok) {
             printf("Gecersiz secim.\n");
             continue;
         }

Also applies to: 95-98

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sifreleyicim/sifreleyicim1/sifreleyici.c` around lines 17 - 27, satir_oku
currently treats fgets()==NULL as an empty string and never signals EOF; change
its signature to return an int status (0 for EOF, 1 for success), on
fgets()==NULL return 0 (do not set dizi to ""), after a successful read check if
the newline was present and if not drain stdin until '\n' to discard the
remainder of the overlong input; update sayi_oku to propagate EOF by returning
-1 when satir_oku returns 0, and update main to check for -1 from sayi_oku and
break/exit the input loop instead of treating it as an invalid choice.


void sifreleyici(int kaydirma, char kucultulmus_dizi[], FILE* output_file) {
char sifrelenmis_dizi[MAX_UZUNLUK] = {0};
int index = 0;

for (int i = 0; i < (int)strlen(kucultulmus_dizi); i++) {
char anlik_karakter = kucultulmus_dizi[i];
if (isalpha(anlik_karakter)) {
char sifrelenmis_karakter = 'a' + (anlik_karakter - 'a' + kaydirma) % 26;
sifrelenmis_dizi[index++] = sifrelenmis_karakter;
} else {
sifrelenmis_dizi[index++] = anlik_karakter;
}
char kaydir_char(char c, int shift) {
if (c >= 'a' && c <= 'z') {
return (char)('a' + (c - 'a' + shift) % ALFABE_UZUNLUGU);
}

sifrelenmis_dizi[index] = '\0';
fprintf(output_file, "%s", sifrelenmis_dizi);
if (c >= 'A' && c <= 'Z') {
return (char)('A' + (c - 'A' + shift) % ALFABE_UZUNLUGU);
}
return c;
}

void sifre_Coz(char dizi[MAX_UZUNLUK], FILE* outputFile) {
char cozulmus_var[2 * MAX_UZUNLUK] = {0};
void sifrele_metin(const char metin[], int kaydirma, char cikti[]) {
int shift = normalize_shift(kaydirma);

for (int kaydirma = 0; kaydirma <= 255; kaydirma++) {
int varIndex = 0;
for (int i = 0; metin[i] != '\0'; i++) {
cikti[i] = kaydir_char(metin[i], shift);
}

for (int i = 0; i < (int)strlen(dizi); i++) {
char anlik_karakter = dizi[i];
cikti[strlen(metin)] = '\0';
}

if (isalpha(anlik_karakter)) {
char cozulmus_karakter = 'a' + ((anlik_karakter - 'a' - kaydirma + 26) % 26);
cozulmus_var[varIndex++] = cozulmus_karakter;
} else {
cozulmus_var[varIndex++] = anlik_karakter;
}
}
void tum_cozumleri_yazdir(const char metin[]) {
char gecici[MAX_UZUNLUK];

cozulmus_var[varIndex] = '\0';
for (int kaydirma = 0; kaydirma < ALFABE_UZUNLUGU; kaydirma++) {
for (int i = 0; metin[i] != '\0'; i++) {
gecici[i] = kaydir_char(metin[i], ALFABE_UZUNLUGU - kaydirma);
}
gecici[strlen(metin)] = '\0';

fprintf(outputFile, "\n*************************\n");
fprintf(outputFile, "VARIANT %d: %s", kaydirma, cozulmus_var);
fprintf(outputFile, "\n*************************\n");
printf("[%2d] %s\n", kaydirma, gecici);
}
}

int main() {
int secim = 0;
int sayi_oku(const char* prompt, int* sonuc) {
char satir[64];

ana_menu:
printf("Hello, what do you want to do?\n1) DECODE\n2) ENCODE\n-> ");
scanf("%d", &secim);
printf("%s", prompt);
satir_oku(satir, sizeof(satir));

if (secim == 2) {
char kucultulmus_dizi[MAX_UZUNLUK];
int kaydirma = 0;
char* endptr = NULL;
long deger = strtol(satir, &endptr, 10);

FILE* input_file = fopen("sifreli_text.txt", "w");
FILE* output_file = fopen("sifresiz_text.txt", "r");
if (can_file_open(output_file, input_file)) {
// Dosya açılamadıysa programı sonlandırıyoruz
return 1;
}
if (satir[0] == '\0' || (endptr != NULL && *endptr != '\0')) {
return 0;
}

system("clear"); // Linux'ta ekran temizleme
printf("DON'T FORGET TO SAVE\n");
*sonuc = (int)deger;
return 1;
Comment on lines +68 to +76

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm that sayi_oku() currently uses strtol() without range/error guards.
sed -n '62,76p' sifreleyicim/sifreleyicim1/sifreleyici.c
printf '\n-- guard search --\n'
rg -n 'strtol|errno|ERANGE|INT_(MIN|MAX)' sifreleyicim/sifreleyicim1/sifreleyici.c || true

Repository: ukis666/Ceasar_Cipher_Decoder_and_Encoder

Length of output: 486


🏁 Script executed:

head -20 sifreleyicim/sifreleyicim1/sifreleyici.c

Repository: ukis666/Ceasar_Cipher_Decoder_and_Encoder

Length of output: 532


Reject out-of-range numeric input before narrowing to int.

strtol() parses into long, but *sonuc = (int)deger; happens without checking errno or bounds. Values outside the platform int range (e.g., 2147483648 on a 32-bit int system) are accepted and silently truncated instead of triggering validation error.

Add the missing headers:

+#include <errno.h>
+#include <limits.h>

Then guard the parse and cast:

+    errno = 0;
     char* endptr = NULL;
     long deger = strtol(satir, &endptr, 10);
 
-    if (satir[0] == '\0' || (endptr != NULL && *endptr != '\0')) {
+    if (satir[0] == '\0' || *endptr != '\0' ||
+        errno == ERANGE || deger < INT_MIN || deger > INT_MAX) {
         return 0;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
char* endptr = NULL;
long deger = strtol(satir, &endptr, 10);
FILE* input_file = fopen("sifreli_text.txt", "w");
FILE* output_file = fopen("sifresiz_text.txt", "r");
if (can_file_open(output_file, input_file)) {
// Dosya açılamadıysa programı sonlandırıyoruz
return 1;
}
if (satir[0] == '\0' || (endptr != NULL && *endptr != '\0')) {
return 0;
}
system("clear"); // Linux'ta ekran temizleme
printf("DON'T FORGET TO SAVE\n");
*sonuc = (int)deger;
return 1;
errno = 0;
char* endptr = NULL;
long deger = strtol(satir, &endptr, 10);
if (satir[0] == '\0' || *endptr != '\0' ||
errno == ERANGE || deger < INT_MIN || deger > INT_MAX) {
return 0;
}
*sonuc = (int)deger;
return 1;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sifreleyicim/sifreleyicim1/sifreleyici.c` around lines 68 - 76, Include
<errno.h> and <limits.h>, set errno = 0 before calling strtol(satir, &endptr,
10), then after the call reject the parse if errno == ERANGE or if deger <
INT_MIN || deger > INT_MAX; keep the existing empty-string and endptr checks
(satir[0] == '\0' || (endptr != NULL && *endptr != '\0')) and return 0 on those
failures, only cast and assign *sonuc = (int)deger and return 1 when no errors
and value is within int range.

}

// Linux'ta metin dosyası açmak için (Varsayılan program) xdg-open kullanabilirsiniz:
system("xdg-open sifresiz_text.txt");
void menu_yazdir(void) {
printf("\n=== Caesar Cipher (Linux CLI) ===\n");
printf("1) Encode\n");
printf("2) Decode (all 26 variants)\n");
printf("0) Exit\n");
printf("Secim: ");
}

system("clear");
printf("Enter how many shifts you want (enter -1 to see the encryption table): ");
scanf("%d", &kaydirma);
int main(void) {
char metin[MAX_UZUNLUK];
char cikti[MAX_UZUNLUK];

if (kaydirma == -1) {
system("clear");
// Örnek tablo
printf("1- A->B 2- A->C 3- A->D 4- A->E 5- A->F 6- A->G\n");
printf("...\n25- A->Z\n\n\n");
goto ana_menu;
}
while (1) {
int secim = -1;
menu_yazdir();

Kucuk_Harf_Dizi(kucultulmus_dizi, output_file);
sifreleyici(kaydirma, kucultulmus_dizi, input_file);
fclose(input_file);

FILE* bakma = fopen("sifreli_text.txt", "r");
system("clear");
printf("ENCRYPTED FILE\n");
system("xdg-open sifreli_text.txt");
if (bakma) fclose(bakma);
fclose(output_file);
system("clear");

// Dosyaları kapatıp sıfırlamak için tekrar aç
FILE* input_file_silme = fopen("sifreli_text.txt", "w");
FILE* output_file_silme = fopen("sifresiz_text.txt", "w");
if (input_file_silme) {
fprintf(input_file_silme, " ");
fclose(input_file_silme);
}
if (output_file_silme) {
fprintf(output_file_silme, " ");
fclose(output_file_silme);
if (!sayi_oku("", &secim)) {
printf("Gecersiz secim.\n");
continue;
}

goto ana_menu;
}
else if (secim == 1) {
char kucultulmus_dizi[MAX_UZUNLUK];
FILE* input_file = fopen("sifreli_text.txt", "r");
FILE* output_file = fopen("sifresiz_text.txt", "w");
if (can_file_open(input_file, output_file)) {
return 1;
if (secim == 0) {
printf("Cikis yapildi.\n");
break;
}

system("clear");
printf("DON'T FORGET TO SAVE\n");
system("xdg-open sifreli_text.txt");
if (secim == 1) {
int kaydirma;

Kucuk_Harf_Dizi(kucultulmus_dizi, input_file);
sifre_Coz(kucultulmus_dizi, output_file);
fclose(output_file);
printf("Metni girin: ");
satir_oku(metin, sizeof(metin));

system("clear");
printf("CRACKED TEXT\n");
system("xdg-open sifresiz_text.txt");

fclose(input_file);

system("clear");
if (!sayi_oku("Kaydirma miktari: ", &kaydirma)) {
printf("Gecersiz kaydirma degeri.\n");
continue;
}

// Dosyaları kapatıp sıfırlamak için tekrar aç
FILE* input_file_silme = fopen("sifreli_text.txt", "w");
FILE* output_file_silme = fopen("sifresiz_text.txt", "w");
if (input_file_silme) {
fprintf(input_file_silme, " ");
fclose(input_file_silme);
sifrele_metin(metin, kaydirma, cikti);
printf("Sifreli metin: %s\n", cikti);
}
if (output_file_silme) {
fprintf(output_file_silme, " ");
fclose(output_file_silme);
else if (secim == 2) {
printf("Sifreli metni girin: ");
satir_oku(metin, sizeof(metin));
tum_cozumleri_yazdir(metin);
}
else {
printf("Bilinmeyen secim.\n");
}

goto ana_menu;
}

return 0;
Expand Down