48 lines
1.2 KiB
Go
48 lines
1.2 KiB
Go
package infra
|
|
|
|
import (
|
|
"path/filepath"
|
|
"strings"
|
|
"unicode"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// FileUniqueName genera un nombre de archivo unico combinando un UUID v4 con la
|
|
// extension sanitizada del nombre original.
|
|
//
|
|
// Ejemplo: "vacaciones.PNG" -> "a1b2c3d4-e5f6-7890-abcd-ef1234567890.png"
|
|
//
|
|
// La extension se sanitiza: solo se conservan caracteres alfanumericos en minusculas
|
|
// y se trunca a 16 caracteres como maximo. Si el archivo no tiene extension, se
|
|
// retorna solo el UUID.
|
|
//
|
|
// La funcion es "pura en intencion" en el sentido de que su firma no depende del
|
|
// contexto, pero internamente usa un generador de UUIDs aleatorios — el resultado
|
|
// no es determinista.
|
|
func FileUniqueName(originalName string) string {
|
|
id := uuid.NewString()
|
|
|
|
ext := filepath.Ext(originalName)
|
|
ext = strings.TrimPrefix(ext, ".")
|
|
ext = sanitizeExt(ext)
|
|
if ext == "" {
|
|
return id
|
|
}
|
|
return id + "." + ext
|
|
}
|
|
|
|
// sanitizeExt deja solo caracteres alfanumericos en minusculas y trunca a 16 chars.
|
|
func sanitizeExt(ext string) string {
|
|
var b strings.Builder
|
|
for _, r := range strings.ToLower(ext) {
|
|
if unicode.IsLetter(r) || unicode.IsDigit(r) {
|
|
b.WriteRune(r)
|
|
}
|
|
if b.Len() >= 16 {
|
|
break
|
|
}
|
|
}
|
|
return b.String()
|
|
}
|