This should do more or less what you request.
(defun dired-duplicate-this-file ()
"Duplicate file on this line."
(interactive)
(let* ((this (dired-get-filename t))
(ctr 1)
(new (format "%s[%d]" this ctr)))
(while (file-exists-p new)
(setq ctr (1+ ctr)
new (format "%s[%d]" this ctr)))
(dired-copy-file this new nil))
(revert-buffer))
That copies a file foo to foo[1], or foo[2] if foo[1] exists, etc.
If you want a different naming convention, e.g., foo Copy, foo Copy (2), etc. then use something like this:
(defun dired-duplicate-this-file ()
"Duplicate file on this line."
(interactive)
(let* ((this (dired-get-filename t))
(ctr 1)
(new (format "%s Copy" this)))
(while (file-exists-p new)
(setq ctr (1+ ctr)
new (format "%s Copy (%d)" this ctr)))
(dired-copy-file this new nil))
(revert-buffer))
Of course, if you duplicate a file such as foo[2] or foo Copy (2) then you'll get files named like foo[2][1], foo[2][2], ... or foo Copy (2) Copy, foo Copy (2) Copy (2), ...
And if your file has an extension, such as .txt, then the new name will be something like foo.txt[1] or foo.txt Copy. Not sure if that's what you want. If not, you can use functions file-name-sans-extension and file-name-extension to move the extension after the number (if that's what you want), so you get foo[1].txt or foo Copy.txt. It all depends on what you want.
Function format lets you specify the form you want. See C-h f format for info.